Open atty303 opened 1 week ago
Though I don't know well about jackson-databind, if we just want to convert %
into/from YAML/TOML/JSON via jackson-databind, it seems like enough to implement ObjectMapper or Converter that maps %
into jackson's internal structure.
Supposing R <: %
, because our record type R
is not class itself, we should need some hack.
% scala-cli --dep com.fasterxml.jackson.core:jackson-databind:2.17.1 --dep com.github.tarao::record4s:0.13.0
Welcome to Scala 3.4.2 (17, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> import com.github.tarao.record4s.%
scala> type Person = %{
| val name: String
| val age: Int
| }
// defined alias type Person = com.github.tarao.record4s.%{val name: String; val age: Int}
scala> import com.fasterxml.jackson.databind.ObjectMapper
scala> val m = new ObjectMapper();
val m: com.fasterxml.jackson.databind.ObjectMapper = com.fasterxml.jackson.databind.ObjectMapper@1b26fac2
scala> val p: Person = m.readValue("""{"name":"windymelt","age":30}""", classOf[Person])
-- [E170] Type Error: ----------------------------------------------------------
1 |val p: Person = m.readValue("""{"name":"windymelt","age":30}""", classOf[Person])
| ^^^^^^
| Person is not a class type
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val p: Person = %(name="Windymelt", age=30)
val p: Person = %(name = Windymelt, age = 30)
scala> p.getClass
val res0: Class[? <: Person] = class com.github.tarao.record4s.MapRecord
scala> val pp: Person = m.readValue("""{"name":"windymelt","age":30}""", p.getClass)
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.github.tarao.record4s.MapRecord` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1887)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1375)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1508)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816)
... 32 elided
Integration with Jackson would be useful to be able to read and write YAML and TOML via jackson-dataformats-text. I'll try myself if I have time, but I'm not familiar with any of Scala3/Record4s/Jackson, so I'd be happy to implement it for those who are familiar with them. (After a little touch and go, it seemed difficult to avoid Type Erasure)