0

I have a class and a custom serializer for it. Also I have a Layer object and another serializer and descriptor for it.

internal data class LayerItem(
    internal var x: Float = 0f,
    internal var y: Float = 0f,
    internal var w: Float = 100f,
    internal var h: Float = 100f,
    internal var rotation: Float = 0f,
    internal val type: String,
    internal val layerId: String = UUID.randomUUID().toString().uppercase(Locale.ENGLISH),
    internal var layer: Layer
)
...
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("LayerItem") {
                element<Float>("x")
                element<Float>("y")
                element<Float>("w")
                element<Float>("h")
                element<Float>("rotation")
                element<String>("type")
                element<String>("uid")
                element<Layer>("layer")
            }

        override fun serialize(encoder: Encoder, value: LayerItem?) {
           encoder.encodeStructure(descriptor){
               encodeSerializableElement(descriptor,0,Float.serializer(), value?.x ?: 0f)
               encodeSerializableElement(descriptor,1,Float.serializer(), value?.y ?: 0f)
               encodeSerializableElement(descriptor,2,Float.serializer(), value?.w ?: 0f)
               encodeSerializableElement(descriptor,3,Float.serializer(), value?.h ?: 0f)
               encodeSerializableElement(descriptor,4,Float.serializer(), value?.rotation ?: 0f)
               encodeSerializableElement(descriptor,5,String.serializer(), value?.type ?: "")
               encodeSerializableElement(descriptor,6,String.serializer(), value?.layerId ?: UUID.randomUUID().toString().uppercase(Locale.ENGLISH))
               when (value?.type) {
                    Image.value -> encodeSerializableElement(descriptor,7,ImageLayer.serializer(), value.layer as ImageLayer)
                    Video.value -> encodeSerializableElement(descriptor,7,VideoLayer.serializer(), value.layer as VideoLayer)
                    Link.value -> encodeSerializableElement(descriptor,7,LinkLayer.serializer(), value.layer as LinkLayer)
                    Text.value -> encodeSerializableElement(descriptor,7,TextLayer.serializer(), value.layer as TextLayer)
                    else -> null
                }
            }
        }

When I serialize it and write it to Json with json.encodeToString(LayerItem.serializer(),layerItem)), it outputs as:

{
        "x": 30.0,
        "y": 30.0,
        "w": 15.320556,
        "h": 6.0,
        "rotation": 0.0,
        "type": "link",
        "uid": "00071DA5-2C27-44C2-9930-1A998758EA99",
        "layer": {
            "text": "123",
            "link": "abc.com",
            "textColor": "#ffad27ff",
            "bgColor": "#ffffffff"
        }
    }

Is there a way to serialize object without putting it to element and opening new structure? I want output as


{
        "x": 30.0,
        "y": 30.0,
        "w": 15.320556,
        "h": 6.0,
        "rotation": 0.0,
        "type": "link",
        "uid": "00071DA5-2C27-44C2-9930-1A998758EA99",
        "text": "123",
        "link": "abc.com",
        "textColor": "#ffad27ff",
        "bgColor": "#ffffffff"
    }
arda türkoğlu
  • 123
  • 1
  • 1
  • 5
  • I think you need to **[1]** change the custom descriptor to match the desired output (replace `element("layer")` with the fields of `Layer`, and **[2]** directly serialize the fields of `value.layer`, not pass in `value.layer` into `encodeSerializableElement()`. Although, I'd recommend not writing a custom serializer (because the plugin generated ones work well, and are less work to maintain), but instead write DTOs that more accurately reflect the JSON you want to see. – aSemy Oct 09 '22 at 11:43

0 Answers0