@@ -2,22 +2,32 @@ package at.asitplus.jsonpath.core
22
33import at.asitplus.jsonpath.generated.JsonPathLexer
44import at.asitplus.jsonpath.generated.JsonPathParser
5+ import kotlinx.serialization.KSerializer
56import kotlinx.serialization.Serializable
7+ import kotlinx.serialization.descriptors.SerialDescriptor
8+ import kotlinx.serialization.encoding.Decoder
9+ import kotlinx.serialization.encoding.Encoder
10+ import kotlinx.serialization.json.JsonDecoder
11+ import kotlinx.serialization.json.JsonElement
12+ import kotlinx.serialization.json.jsonPrimitive
13+ import kotlinx.serialization.json.long
614import org.antlr.v4.kotlinruntime.CharStreams
715import org.antlr.v4.kotlinruntime.CommonTokenStream
816import org.antlr.v4.kotlinruntime.ListTokenSource
17+ import kotlin.jvm.JvmInline
918
1019/* *
1120 * specification: https://datatracker.ietf.org/doc/rfc9535/
1221 * date: 2024-02
1322 * section: 2.7. Normalized Paths
1423 */
15- @Serializable
24+ @Serializable(with = NormalizedJsonPathSegment . JsonDistinguishableSerializer :: class )
1625sealed interface NormalizedJsonPathSegment {
1726 fun toNormalizedJsonPathSegmentString (): String
1827
1928 @Serializable
20- data class NameSegment (val memberName : String ) : NormalizedJsonPathSegment {
29+ @JvmInline
30+ value class NameSegment (val memberName : String ) : NormalizedJsonPathSegment {
2131 override fun toNormalizedJsonPathSegmentString () = toString()
2232
2333 override fun toString (): String {
@@ -48,7 +58,8 @@ sealed interface NormalizedJsonPathSegment {
4858 }
4959
5060 @Serializable
51- data class IndexSegment (val index : UInt ) : NormalizedJsonPathSegment {
61+ @JvmInline
62+ value class IndexSegment (val index : UInt ) : NormalizedJsonPathSegment {
5263 companion object {
5364 operator fun invoke (int : Int ) = IndexSegment (int.also {
5465 require(int >= 0 )
@@ -61,4 +72,38 @@ sealed interface NormalizedJsonPathSegment {
6172 return " [$index ]"
6273 }
6374 }
75+
76+ class JsonDistinguishableSerializer : KSerializer <NormalizedJsonPathSegment > {
77+ override val descriptor: SerialDescriptor
78+ get() = SerialDescriptor (
79+ original = JsonElement .serializer().descriptor,
80+ serialName = JsonDistinguishableSerializer ::class .qualifiedName!! ,
81+ )
82+
83+ override fun serialize (
84+ encoder : Encoder ,
85+ value : NormalizedJsonPathSegment
86+ ) {
87+ when (value) {
88+ is IndexSegment -> encoder.encodeLong(value.index.toLong())
89+ is NameSegment -> encoder.encodeString(value.memberName)
90+ }
91+ }
92+
93+ override fun deserialize (decoder : Decoder ): NormalizedJsonPathSegment {
94+ require(decoder is JsonDecoder ) {
95+ " Expected decoder to be ${JsonDecoder ::class .qualifiedName!! } , but was `$decoder `."
96+ }
97+ val jsonElement = decoder.decodeJsonElement().jsonPrimitive
98+ return if (jsonElement.isString) {
99+ NameSegment (jsonElement.content)
100+ } else {
101+ IndexSegment (jsonElement.long.also {
102+ require(it >= 0 ) {
103+ " Expected index segment to be non-negative, but got `$it `."
104+ }
105+ }.toUInt())
106+ }
107+ }
108+ }
64109}
0 commit comments