The forward path in MutableSchemaBasedValueProcessor.processFallback converts Fallback.Left / Right / Both into DynamicValue.LeftValue / RightValue / BothValue. The reverse path in DynamicValue.toTypedValueLazyError has cases for those DynamicValue shapes against Schema.Either, but no cases for them against Schema.Fallback, and no case at all for BothValue. So fromSchemaAndValue(fallbackSchema, v).toTypedValue(fallbackSchema) always returns Left(CastError) for every Fallback variant.
Reproducer (scala-cli):
//> using scala 3.8.3
//> using dep dev.zio::zio-schema::1.8.5
//> using dep dev.zio::zio-schema-derivation::1.8.5
import zio.schema.*
@main def repro(): Unit =
val schema: Schema[Fallback[String, Int]] = Schema.Fallback(Schema[String], Schema[Int])
for v <- Seq[Fallback[String, Int]](
Fallback.Left("hello"),
Fallback.Right(42),
Fallback.Both("hello", 42)
)
do
val dyn = DynamicValue.fromSchemaAndValue(schema, v)
val back = dyn.toTypedValue(schema)
println(s"$v -> $back")
Output:
Left(hello) -> Left(Failed to cast LeftValue(...) to schema Fallback(...))
Right(42) -> Left(Failed to cast RightValue(...) to schema Fallback(...))
Both(hello, 42) -> Left(Failed to cast BothValue(...) to schema Fallback(...))
Source: https://github.com/zio/zio-schema/blob/f32240d525c45a702aaa40e9fb50f25011dc003a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala — toTypedValueLazyError covers (LeftValue, Schema.Either) and (RightValue, Schema.Either) but never their Schema.Fallback counterparts, and BothValue is unhandled altogether.
Versions. zio-schema 1.8.5, Scala 3.8.3.
Suggested fix. Add the three missing cases:
case (DynamicValue.LeftValue(value), Schema.Fallback(s1, _, _, _)) =>
value.toTypedValueLazyError(s1).map(Fallback.Left(_))
case (DynamicValue.RightValue(value), Schema.Fallback(_, s2, _, _)) =>
value.toTypedValueLazyError(s2).map(Fallback.Right(_))
case (DynamicValue.BothValue(l, r), Schema.Fallback(s1, s2, _, _)) =>
for
lv <- l.toTypedValueLazyError(s1)
rv <- r.toTypedValueLazyError(s2)
yield Fallback.Both(lv, rv)
Happy to PR.
The forward path in
MutableSchemaBasedValueProcessor.processFallbackconvertsFallback.Left/Right/BothintoDynamicValue.LeftValue/RightValue/BothValue. The reverse path inDynamicValue.toTypedValueLazyErrorhas cases for thoseDynamicValueshapes againstSchema.Either, but no cases for them againstSchema.Fallback, and no case at all forBothValue. SofromSchemaAndValue(fallbackSchema, v).toTypedValue(fallbackSchema)always returnsLeft(CastError)for everyFallbackvariant.Reproducer (scala-cli):
Output:
Source: https://github.com/zio/zio-schema/blob/f32240d525c45a702aaa40e9fb50f25011dc003a/zio-schema/shared/src/main/scala/zio/schema/DynamicValue.scala —
toTypedValueLazyErrorcovers(LeftValue, Schema.Either)and(RightValue, Schema.Either)but never theirSchema.Fallbackcounterparts, andBothValueis unhandled altogether.Versions. zio-schema 1.8.5, Scala 3.8.3.
Suggested fix. Add the three missing cases:
Happy to PR.