Skip to content

Commit

Permalink
Change serialize function to interface
Browse files Browse the repository at this point in the history
  • Loading branch information
marychatte committed Oct 8, 2024
1 parent 0414168 commit 14708d0
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public fun Route.sse(handler: suspend SSESession.() -> Unit): Unit = processSSE(
*/
public fun Route.sse(
path: String,
serialize: (TypeInfo, Any) -> String = { _, it -> it.toString() },
serialize: Serializer,
handler: suspend SSESessionWithSerialization.() -> Unit
) {
route(path, HttpMethod.Get) {
Expand All @@ -70,12 +70,12 @@ public fun Route.sse(
* @see SSESessionWithSerialization
*/
public fun Route.sse(
serialize: (TypeInfo, Any) -> String = { _, it -> it.toString() },
serialize: Serializer,
handler: suspend SSESessionWithSerialization.() -> Unit
): Unit = processSSE(serialize, handler)

private fun Route.processSSE(
serialize: ((TypeInfo, Any) -> String)?,
serialize: Serializer?,
handler: suspend SSESessionWithSerialization.() -> Unit
) {
plugin(SSE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import kotlinx.coroutines.*
*/
public class SSEServerContent<T : SSESession>(
public val call: ApplicationCall,
public val serialize: ((TypeInfo, Any) -> String)?,
public val serialize: Serializer?,
public val handle: suspend T.() -> Unit
) : OutgoingContent.WriteChannelContent() {
override val contentType: ContentType = ContentType.Text.EventStream
Expand All @@ -40,7 +40,7 @@ public class SSEServerContent<T : SSESession>(
session = DefaultServerSSESession(channel, call, coroutineContext) as T
if (serialize != null) {
session = object : SSESessionWithSerialization, SSESession by session as DefaultServerSSESession {
override val serializer: (TypeInfo, Any) -> String = serialize
override val serializer: Serializer = serialize
} as T
}
session?.handle()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public interface SSESessionWithSerialization : SSESession {
/**
* Serializer for transforming data object into field `data` of `ServerSentEvent`.
*/
public val serializer: (TypeInfo, Any) -> String
public val serializer: Serializer
}

public suspend inline fun <reified T : Any> SSESessionWithSerialization.sendSerialized(
Expand All @@ -77,7 +77,7 @@ public suspend inline fun <reified T : Any> SSESessionWithSerialization.sendSeri
send(
ServerSentEvent(
event.data?.let {
serializer(typeInfo<T>(), it)
serializer.serialize(typeInfo<T>(), it)
},
event.event,
event.id,
Expand All @@ -98,5 +98,17 @@ public suspend inline fun <reified T : Any> SSESessionWithSerialization.sendSeri
}

public suspend inline fun <reified T : Any> SSESessionWithSerialization.sendSerialized(data: T) {
send(ServerSentEvent(serializer(typeInfo<T>(), data)))
send(ServerSentEvent(serializer.serialize(typeInfo<T>(), data)))
}


/**
* Serializer interface for transforming data object into field `data` of `ServerSentEvent`.
*/
public interface Serializer {

/**
* Transforms data object into field `data` of `ServerSentEvent`.
*/
public fun serialize(typeInfo: TypeInfo, data: Any): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.testing.*
import io.ktor.sse.*
import io.ktor.util.reflect.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.serialization.*
Expand Down Expand Up @@ -201,14 +202,16 @@ class ServerSentEventsTest {
fun testSerializerInRoute() = testApplication {
install(SSE)
routing {
sse("/person", serialize = { typeInfo, data ->
when (typeInfo.type) {
Person1::class -> {
"Age ${(data as Person1).age}"
}

else -> {
data.toString()
sse("/person", object : Serializer {
override fun serialize(typeInfo: TypeInfo, data: Any): String {
return when (typeInfo.type) {
Person1::class -> {
"Age ${(data as Person1).age}"
}

else -> {
data.toString()
}
}
}
}) {
Expand All @@ -231,21 +234,24 @@ class ServerSentEventsTest {
fun testDifferentSerializers() = testApplication {
install(SSE)
routing {
sse(serialize = { typeInfo, data ->
when (typeInfo.type) {
Person1::class -> {
"Age ${(data as Person1).age}"
}

Person2::class -> {
"Number ${(data as Person2).number}"
}

else -> {
data.toString()
sse(object : Serializer {
override fun serialize(typeInfo: TypeInfo, data: Any): String {
return when (typeInfo.type) {
Person1::class -> {
"Age ${(data as Person1).age}"
}

Person2::class -> {
"Number ${(data as Person2).number}"
}

else -> {
data.toString()
}
}
}
}) {
})
{
sendSerialized(Person1(22))
sendSerialized(Person2(123456))
}
Expand Down Expand Up @@ -275,9 +281,11 @@ class ServerSentEventsTest {
fun testJsonDeserializer() = testApplication {
install(SSE)
routing {
sse("/json", serialize = { typeInfo, it ->
val serializer = Json.serializersModule.serializer(typeInfo.kotlinType!!)
Json.encodeToString(serializer, it)
sse("/json", object : Serializer {
override fun serialize(typeInfo: TypeInfo, data: Any): String {
val serializer = Json.serializersModule.serializer(typeInfo.kotlinType!!)
return Json.encodeToString(serializer, data)
}
}) {
sendSerialized(Customer(0, "Jet", "Brains"))
sendSerialized(Product(0, listOf(100, 200)))
Expand Down

0 comments on commit 14708d0

Please sign in to comment.