[{"name":"Bytes.Decoder","comment":" Fast bytes decoder with error reporting and `oneOf` branching.\n\n\n# Architecture\n\nEach `Decoder` carries two execution strategies:\n\n1.  **Fast path** — a raw `elm/bytes` `Bytes.Decode.Decoder` composed via\n    `Decode.map2`, `Decode.andThen`, `Decode.loop`, etc. When present, `decode`\n    executes a single `Decode.decode` call with zero per-step overhead. This\n    matches the performance of hand-written `elm/bytes` decoders.\n\n2.  **Slow path** — a state-passing function that tracks byte offsets, reports\n    structured errors, and supports backtracking in `oneOf`. This path is only\n    executed when the fast path is unavailable or returns `Nothing` (i.e. an\n    error occurred).\n\nThe key insight is that most decoders succeed on well-formed input. By deferring\nerror tracking to a re-decode, the happy path pays no cost for error reporting.\n\n\n# Fast-path availability\n\nNot every combinator can be expressed as a raw `Bytes.Decode.Decoder`:\n\n  - **Always fast**: `succeed`, `map`, `map2`–`map5`, `keep`, `ignore`, `skip`,\n    `andThen`, `loop`, `repeat`, and all primitives.\n  - **Always slow**: `fail` (no decoder can produce a value), `oneOf`\n    (requires backtracking which `Bytes.Decode.Decoder` cannot do mid-stream).\n  - **Conditionally fast**: `andThen` and `loop` remain fast as long as the\n    callback returns a decoder with a fast path. If a callback branch returns\n    `fail`, that branch uses `Decode.fail` to signal the raw decoder, which causes\n    `Decode.decode` to return `Nothing` and triggers the slow re-decode.\n\nIn practice, `fail` branches inside `andThen` are error-handling code that only\nruns on malformed input — exactly when we want to re-decode with error tracking.\n\n\n# Running\n\n@docs Decoder, decode, Error\n\n\n# Static\n\n@docs succeed, fail, inContext\n\n\n# Primitives\n\n\n## Integers\n\n@docs unsignedInt8, unsignedInt16, unsignedInt32, signedInt8, signedInt16, signedInt32\n\n\n## Floats\n\n@docs float32, float64\n\n\n## Strings\n\n@docs string\n\n\n## Raw Bytes\n\n@docs bytes\n\n\n# Mapping\n\n@docs map, map2, map3, map4, map5\n\n\n# Pipeline\n\n@docs keep, ignore, skip\n\n\n# Chaining\n\n@docs andThen, oneOf, repeat, Step, loop\n\n\n# Random access\n\n@docs Position, position, startOfInput, randomAccess\n\n","unions":[{"name":"Decoder","comment":" A decoder that reads binary data and produces either a value or an error.\n\nInternally, it carries an optional raw `Bytes.Decode.Decoder` (fast path) and a\nstate-passing function (slow path for error reporting).\n\n","args":["context","error","value"],"cases":[]},{"name":"Error","comment":" Describes errors that arise while decoding.\n\nCustom errors happen through [`fail`](#fail), context tracking happens through\n[`inContext`](#inContext).\n\n","args":["context","error"],"cases":[["InContext",["{ label : context, start : Basics.Int }","Bytes.Decoder.Error context error"]],["OutOfBounds",["{ at : Basics.Int, bytes : Basics.Int }"]],["Custom",["{ at : Basics.Int }","error"]],["BadOneOf",["{ at : Basics.Int }","List.List (Bytes.Decoder.Error context error)"]]]},{"name":"Position","comment":" An opaque position in the input, obtained via [`position`](#position).\n","args":[],"cases":[]},{"name":"Step","comment":" Represent the next step of a loop: either continue with updated state,\nor finish with a final value.\n","args":["state","a"],"cases":[["Loop",["state"]],["Done",["a"]]]}],"aliases":[],"values":[{"name":"andThen","comment":" Decode one thing, then decode another thing based on the result.\n\nThe fast path uses `Decode.andThen`. If the callback returns a decoder without\na fast path (e.g. via `fail`), the fast decoder signals failure via\n`Decode.fail`, causing `decode` to fall back to the slow path.\n\n","type":"(a -> Bytes.Decoder.Decoder context error b) -> Bytes.Decoder.Decoder context error a -> Bytes.Decoder.Decoder context error b"},{"name":"bytes","comment":" Decode exactly `n` bytes.\n","type":"Basics.Int -> Bytes.Decoder.Decoder context error Bytes.Bytes"},{"name":"decode","comment":" Run the given decoder on the provided bytes.\n\nFirst tries the fast path (a single `Decode.decode` call). If the fast path is\nunavailable or fails, re-decodes with the slow path to produce a detailed error.\n\n","type":"Bytes.Decoder.Decoder context error value -> Bytes.Bytes -> Result.Result (Bytes.Decoder.Error context error) value"},{"name":"fail","comment":" Always fail with the given error.\n\nThis decoder has no fast path — using it (even in a branch of `andThen`) will\ncause `decode` to fall back to the slow path for error reporting.\n\n","type":"error -> Bytes.Decoder.Decoder context error value"},{"name":"float32","comment":" Decode four bytes as a 32-bit float.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Float"},{"name":"float64","comment":" Decode eight bytes as a 64-bit float.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Float"},{"name":"ignore","comment":" Run a decoder but discard its result, keeping the previous value.\n\nThe ignored decoder must still succeed for the pipeline to succeed.\n\n","type":"Bytes.Decoder.Decoder context error ignore -> Bytes.Decoder.Decoder context error keep -> Bytes.Decoder.Decoder context error keep"},{"name":"inContext","comment":" Add context to errors that may occur during decoding.\n\nThe fast path is preserved (context only matters on the error path).\n\n","type":"context -> Bytes.Decoder.Decoder context error value -> Bytes.Decoder.Decoder context error value"},{"name":"keep","comment":" Decode a value and apply it to the function held by the previous decoder.\n\n    import Bytes.Decoder as BD\n\n    BD.succeed Record\n        |> BD.keep BD.unsignedInt8\n        |> BD.keep BD.unsignedInt8\n        |> BD.keep BD.unsignedInt8\n\n","type":"Bytes.Decoder.Decoder context error a -> Bytes.Decoder.Decoder context error (a -> b) -> Bytes.Decoder.Decoder context error b"},{"name":"loop","comment":" Decode in a loop. Each iteration produces either `Loop` (continue with new\nstate) or `Done` (finish with a value).\n\nThe fast path uses `Decode.loop` (a tight `while` loop in the JS kernel).\nIf any iteration's callback returns a decoder without a fast path, the fast\ndecoder signals failure via `Decode.fail` and `decode` falls back to the slow\npath.\n\n","type":"(state -> Bytes.Decoder.Decoder context error (Bytes.Decoder.Step state a)) -> state -> Bytes.Decoder.Decoder context error a"},{"name":"map","comment":" Transform the value a decoder produces.\n","type":"(a -> b) -> Bytes.Decoder.Decoder context error a -> Bytes.Decoder.Decoder context error b"},{"name":"map2","comment":" Combine what 2 decoders produce.\n","type":"(x -> y -> z) -> Bytes.Decoder.Decoder context error x -> Bytes.Decoder.Decoder context error y -> Bytes.Decoder.Decoder context error z"},{"name":"map3","comment":" Combine what 3 decoders produce.\n","type":"(w -> x -> y -> z) -> Bytes.Decoder.Decoder context error w -> Bytes.Decoder.Decoder context error x -> Bytes.Decoder.Decoder context error y -> Bytes.Decoder.Decoder context error z"},{"name":"map4","comment":" Combine what 4 decoders produce.\n","type":"(v -> w -> x -> y -> z) -> Bytes.Decoder.Decoder context error v -> Bytes.Decoder.Decoder context error w -> Bytes.Decoder.Decoder context error x -> Bytes.Decoder.Decoder context error y -> Bytes.Decoder.Decoder context error z"},{"name":"map5","comment":" Combine what 5 decoders produce.\n","type":"(u -> v -> w -> x -> y -> z) -> Bytes.Decoder.Decoder context error u -> Bytes.Decoder.Decoder context error v -> Bytes.Decoder.Decoder context error w -> Bytes.Decoder.Decoder context error x -> Bytes.Decoder.Decoder context error y -> Bytes.Decoder.Decoder context error z"},{"name":"oneOf","comment":" Try each decoder in order, returning the first success.\n\nThis decoder has no fast path — it always uses the slow path with backtracking.\nFor tag-based dispatch, prefer `andThen` which preserves the fast path.\n\nCollects all errors on failure for diagnostic purposes.\n\n","type":"List.List (Bytes.Decoder.Decoder context error value) -> Bytes.Decoder.Decoder context error value"},{"name":"position","comment":" Produce the current byte offset in the input.\n\nThis decoder has no fast path — using it will cause `decode` to fall back to\nthe slow path.\n\n    import Bytes.Decoder as BD\n\n    BD.decode BD.position (fromList [ 1, 2, 3 ])\n    --> Ok BD.startOfInput\n\n    BD.decode\n        (BD.unsignedInt8\n            |> BD.andThen (\\_ -> BD.position)\n        )\n        (fromList [ 1, 2, 3 ])\n        |> Result.map (\\\\p -> p == BD.startOfInput)\n    --> Ok False\n\n","type":"Bytes.Decoder.Decoder context error Bytes.Decoder.Position"},{"name":"randomAccess","comment":" Read data at an arbitrary offset, then resume where you left off.\n\nThis decoder has no fast path.\n\nAs an example, consider data laid out as:\n\n  - A byte giving the length of a string\n  - A byte giving the absolute offset to the string\n  - Another byte we also need\n\n<!-- -->\n\n    import Bytes exposing (Bytes)\n    import Bytes.Decoder as BD exposing (Decoder)\n    import Bytes.Encode as E\n\n    input : Bytes\n    input =\n        [ E.unsignedInt8 5\n        , E.unsignedInt8 15\n        , E.unsignedInt8 6\n        , E.string (String.repeat 12 \"\\u{0000}\")\n        , E.string \"hello\"\n        ]\n            |> E.sequence\n            |> E.encode\n\n    stringAtOffset : Decoder c e String\n    stringAtOffset =\n        BD.map2 Tuple.pair BD.unsignedInt8 BD.unsignedInt8\n            |> BD.andThen\n                (\\( len, offset ) ->\n                    BD.randomAccess\n                        { offset = offset, relativeTo = BD.startOfInput }\n                        (BD.string len)\n                )\n\n    BD.decode stringAtOffset input\n    --> Ok \"hello\"\n\nParsing continues at the sequential position after `randomAccess` returns:\n\n    final : Decoder c e { string : String, number : Int }\n    final =\n        BD.succeed (\\s n -> { string = s, number = n })\n            |> BD.keep stringAtOffset\n            |> BD.keep BD.unsignedInt8\n\n    BD.decode final input\n    --> Ok { string = \"hello\", number = 6 }\n\n","type":"{ offset : Basics.Int, relativeTo : Bytes.Decoder.Position } -> Bytes.Decoder.Decoder context error value -> Bytes.Decoder.Decoder context error value"},{"name":"repeat","comment":" Decode exactly `count` copies of the same decoder into a list.\n\nIf the inner decoder has a fast path, `repeat` preserves it by composing\na single `Decode.loop` decoder.\n\n","type":"Bytes.Decoder.Decoder context error value -> Basics.Int -> Bytes.Decoder.Decoder context error (List.List value)"},{"name":"signedInt16","comment":" Decode two bytes as a signed integer from -32768 to 32767.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Int"},{"name":"signedInt32","comment":" Decode four bytes as a signed integer from -2147483648 to 2147483647.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Int"},{"name":"signedInt8","comment":" Decode one byte as a signed integer from -128 to 127.\n","type":"Bytes.Decoder.Decoder context error Basics.Int"},{"name":"skip","comment":" Skip `n` bytes, then continue with the given decoder.\n","type":"Basics.Int -> Bytes.Decoder.Decoder context error value -> Bytes.Decoder.Decoder context error value"},{"name":"startOfInput","comment":" The position at the very start of the input (offset 0).\n\nUseful as the `relativeTo` argument in [`randomAccess`](#randomAccess).\n\n","type":"Bytes.Decoder.Position"},{"name":"string","comment":" Decode exactly `n` bytes as a UTF-8 string.\n","type":"Basics.Int -> Bytes.Decoder.Decoder context error String.String"},{"name":"succeed","comment":" Always succeed with the given value, consuming no input.\n","type":"value -> Bytes.Decoder.Decoder context error value"},{"name":"unsignedInt16","comment":" Decode two bytes as an unsigned integer from 0 to 65535.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Int"},{"name":"unsignedInt32","comment":" Decode four bytes as an unsigned integer from 0 to 4294967295.\n","type":"Bytes.Endianness -> Bytes.Decoder.Decoder context error Basics.Int"},{"name":"unsignedInt8","comment":" Decode one byte as an unsigned integer from 0 to 255.\n","type":"Bytes.Decoder.Decoder context error Basics.Int"}],"binops":[]}]