You'll need the scodec.codecs.lazily
combinator to build recursive codecs (not shapeless.lazily
). For 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 and prior, deriving this codec, instead of defining it explicitly, results in an error at compile time, due to the derivation continuing recursively forever. As of 1.8.3, this codec can be automatically derived without issue.
For an example of a recursive tree, see this example from scodec source.