diff --git a/android-bindings/src/main/kotlin/net/aquadc/persistence/android/json/stream.kt b/android-bindings/src/main/kotlin/net/aquadc/persistence/android/json/stream.kt index 3df361af..e4c4852c 100644 --- a/android-bindings/src/main/kotlin/net/aquadc/persistence/android/json/stream.kt +++ b/android-bindings/src/main/kotlin/net/aquadc/persistence/android/json/stream.kt @@ -67,7 +67,7 @@ fun TokenStream.writeTo(writer: JsonWriter): Unit = val tokToJson = enumMapOf( Token.Null, JsonToken.NULL, Token.Bool, JsonToken.BOOLEAN, - /*Token.I8, Token.I16, Token.I32, Token.I64, Token.F32, Token.F64, Token.Str, Token.Blob,*/ + // Token.I8, Token.I16, Token.I32, Token.I64, Token.F32, Token.F64, Token.Str, Token.Blob, Token.BeginSequence, JsonToken.BEGIN_ARRAY, Token.EndSequence, JsonToken.END_ARRAY, Token.BeginDictionary, JsonToken.BEGIN_OBJECT, @@ -118,7 +118,14 @@ fun TokenStream.writeTo(writer: JsonWriter): Unit = return Token.EndDictionary } - val nextTok = if (coerceTo == null) nextToken else tokToJson[coerceTo] + val nextTok = if (coerceTo == null) nextToken else { + if (nextToken == JsonToken.NAME && coerceTo != Token.Str) + // JsonReader can't coerce names to other types, let's do it ourselves + return coerceTo.coerce(reader.nextName().also(_path::onName)) + + tokToJson[coerceTo] + } + return if (nextTok == null) { val value = when (coerceTo!!) { Token.I8 -> reader.nextInt().assertFitsByte() diff --git a/android-bindings/src/test/kotlin/net/aquadc/persistence/android/PersistenceTest.kt b/android-bindings/src/test/kotlin/net/aquadc/persistence/android/PersistenceTest.kt index 5503b06f..3b49c9ac 100644 --- a/android-bindings/src/test/kotlin/net/aquadc/persistence/android/PersistenceTest.kt +++ b/android-bindings/src/test/kotlin/net/aquadc/persistence/android/PersistenceTest.kt @@ -14,6 +14,7 @@ import net.aquadc.persistence.extended.partial import net.aquadc.persistence.struct.Schema import net.aquadc.persistence.struct.Struct import net.aquadc.persistence.struct.build +import net.aquadc.persistence.tokens.Token import net.aquadc.persistence.tokens.readAs import net.aquadc.persistence.tokens.readListOf import net.aquadc.persistence.tokens.tokens @@ -31,11 +32,13 @@ import net.aquadc.persistence.type.set import net.aquadc.persistence.type.string import net.aquadc.properties.persistence.enum import okio.ByteString.Companion.decodeHex +import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertNotSame import org.junit.Assert.assertSame import org.junit.Test import java.io.StringWriter +import java.util.Base64 import java.util.EnumSet @@ -153,8 +156,8 @@ class PersistenceTest { ) } - val smallSchema = Tuple3("a", string, "b", string, "c", string) - val partialSmallSchema = partial(smallSchema) + private val smallSchema = Tuple3("a", string, "b", string, "c", string) + private val partialSmallSchema = partial(smallSchema) @Test fun `json empty partial`() { assertEquals( @@ -238,6 +241,27 @@ class PersistenceTest { ) } + @Test fun coercions() { + val blob = byteArrayOf(1, 2, 3) + val base = Base64.getEncoder().encodeToString(blob) + val tokens = """{"1":"456.789","$base":"123"}""".reader().json().tokens() + + tokens.poll(Token.BeginDictionary) + + assertEquals(Token.Str, tokens.peek()) + assertEquals(1, tokens.poll(Token.I32)) + + assertEquals(Token.Str, tokens.peek()) + assertEquals(456.789, tokens.poll(Token.F64)) + + assertEquals(Token.Str, tokens.peek()) + assertArrayEquals(blob, tokens.poll(Token.Blob) as ByteArray) + + assertEquals(Token.Str, tokens.peek()) + assertEquals(123, tokens.poll(Token.I32)) + + } + private fun read(json: String, type: DataType, lenient: Boolean = false): T = json.reader().json().also { it.isLenient = lenient