scala - define `Codec` for recursive data structure -


i have class looking this,

case class foo ( bar: int, foos: vector[foo] ) 

to define codec[foo], tried this,

def fc = shapeless.lazy((int32 ~~ vector(fc)).widenopt( (foo.apply _).tupled, foo.unapply _ )) 

but did not work, since scodec throws stackoverflowerror. right way of doing ?

you'll need scodec.codecs.lazily combinator build recursive codecs (not shapeless.lazily). example:

scala> def fc: codec[foo] = lazily((int32 :: vector(fc)).as[foo]) fc: scodec.codec[foo]  scala> val res = fc.encode(foo(1, vector(foo(2, vector.empty)))).require res: scodec.bits.bitvector = bitvector(64 bits, 0x0000000100000002)  scala> fc.decode(res) res2: scodec.attempt[scodec.decoderesult[foo]] = successful(decoderesult(foo(1,vector(foo(2,vector()))),bitvector(empty))) 

in scodec 1.8.2 , prior, deriving codec, instead of defining explicitly, results in error @ compile time, due derivation continuing recursively forever. of 1.8.3, codec can automatically derived without issue.

for example of recursive tree, see this example scodec source.


Comments