From f43a6366e44062a5928340599591048a89f7398f Mon Sep 17 00:00:00 2001 From: Louis Pilfold Date: Thu, 19 Dec 2024 12:48:12 +0000 Subject: Recursive decoder --- src/gleam/dynamic/decode.gleam | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/gleam/dynamic/decode.gleam b/src/gleam/dynamic/decode.gleam index 42755d5..bd68c50 100644 --- a/src/gleam/dynamic/decode.gleam +++ b/src/gleam/dynamic/decode.gleam @@ -981,3 +981,34 @@ pub fn new_primitive_decoder( } }) } + +/// Create a decoder that can refer to itself, useful for decoding for deeply +/// nested data. +/// +/// Attempting to create a recursive decoder without this function could result +/// in an infinite loop. If you are using `field` or other `use`able function +/// then you may not need to use this function. +/// +/// ```gleam +/// import gleam/dynamic +/// import decode/zero.{type Decoder} +/// +/// type Nested { +/// Nested(List(Nested)) +/// Value(String) +/// } +/// +/// fn nested_decoder() -> Decoder(Nested) { +/// use <- zero.recursive +/// zero.one_of(zero.string |> zero.map(Value), [ +/// zero.list(nested_decoder()) |> zero.map(Nested), +/// ]) +/// } +/// ``` +/// +pub fn recursive(inner: fn() -> Decoder(a)) -> Decoder(a) { + Decoder(function: fn(data) { + let decoder = inner() + decoder.function(data) + }) +} -- cgit v1.2.3