# API Reference

Generated from `src/avm_cbor.erl` by `scripts/gen-api-docs.py`.

Do not edit this file by hand. Run:

```bash
python3 scripts/gen-api-docs.py
```

## Summary

| Function | Purpose |
|---|---|
| `decode/1` | Decode one CBOR item using default options. |
| `decode/2` | Decode one CBOR item using explicit options. |
| `decode_start/2` | Start a pull-based decode with explicit options. |
| `decode_continue/2` | Advance a continuation by a positive work budget. |
| `decode_all/1` | Decode a complete CBOR sequence using default options. |
| `decode_all/2` | Decode a complete CBOR sequence using explicit options. |
| `decode_sequence/1` | Decode as many complete CBOR items as possible using default options. |
| `decode_sequence/2` | Decode as many complete CBOR items as possible using explicit options. |
| `sequence_fold/3` | Fold complete CBOR sequence items without building a result list. |
| `encode/1` | Encode one supported Erlang value using default options. |
| `encode/2` | Encode one supported Erlang value using explicit options. |
| `encode_with_size/1` | Encode one value and return its exact byte size using default options. |
| `encode_with_size/2` | Encode one value and return its exact byte size using explicit options. |
| `encode_sequence/1` | Encode a list of values as an RFC 8742 CBOR sequence using default options. |
| `encode_sequence/2` | Encode a list of values as an RFC 8742 CBOR sequence using explicit options. |
| `validate_all/1` | Validate exactly one complete CBOR item using default partial-decoding limits. |
| `validate_all/2` | Validate exactly one complete CBOR item using explicit options. |
| `partial_decode/1` | Validate and measure one CBOR item without eagerly constructing nested terms. |
| `partial_decode/2` | Partially decode one CBOR item using explicit options. |
| `partial_value_bytes/1` | Return the complete encoded bytes represented by a partial descriptor. |
| `partial_deep_decode/1` | Materialize the value represented by a partial descriptor. |
| `partial_skip/1` | Discard a validated partial descriptor. |
| `partial_type/1` | Return the CBOR category represented by a partial descriptor. |
| `partial_count/1` | Return an array item count or map pair count. |
| `partial_tag/1` | Return the semantic tag number from a tag descriptor. |
| `partial_size/1` | Return the content size of a byte or text string descriptor. |
| `partial_offset/1` | Return the descriptor item offset. |
| `partial_length/1` | Return the complete encoded length of a descriptor item. |
| `partial_contents/1` | Return encoded child bytes for an array, map, or tag. |
| `partial_map_fold/3` | Fold a map descriptor as opaque key and value descriptors. |
| `partial_array_fold/3` | Fold an array descriptor as opaque element descriptors. |
| `partial_select/2` | Select requested keys from a map descriptor in one pass. |
| `partial_map_find/2` | Find the first matching key in a map descriptor. |
| `partial_array_nth/2` | Return an opaque array element descriptor by zero-based index. |
| `get/2` | Look up a key in a decoded CBOR map. |
| `get/3` | Look up a key in a decoded CBOR map with a default. |
| `require/2` | Require a key in a decoded CBOR map. |
| `as_text/1` | Extract a decoded CBOR text string. |
| `as_bytes/1` | Extract a decoded CBOR byte string. |
| `as_int/1` | Extract a decoded CBOR integer. |
| `as_bool/1` | Extract a decoded CBOR boolean. |
| `ble_options/0` | Return strict options for small BLE-oriented payloads. |

## Functions

### `decode/1`

Decode one CBOR item using default options.

**Spec**

```erlang
decode(term()) -> decode_result()
```

**Example**

```erlang
{ok, 42, <<>>} = avm_cbor:decode(<<16#18, 42>>).
```

**What it does**

Reads one complete CBOR value and returns the decoded value plus trailing bytes.

**What it is not**

It is not a strict whole-binary decoder; use decode_all/1 for that.

### `decode/2`

Decode one CBOR item using explicit options.

**Spec**

```erlang
decode(term(), term()) -> decode_result()
```

**Example**

```erlang
{ok, [1, 2], <<>>} = avm_cbor:decode(<<16#82, 1, 2>>, [{max_items, 3}]).
```

**What it does**

Applies caller-provided limits and feature flags while decoding one item.

**What it is not**

It does not silently ignore invalid options.

### `decode_start/2`

Start a pull-based decode with explicit options.

**Spec**

```erlang
decode_start(term(), term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, State} = avm_cbor:decode_start(<<16#82, 1, 2>>, []),
{done, [1, 2], <<>>} = avm_cbor:decode_continue(State, 100).
```

**What it does**

Returns an opaque immutable continuation without performing parser work.

**What it is not**

It is not a streaming-input API; the complete binary must already exist.

### `decode_continue/2`

Advance a continuation by a positive work budget.

**Spec**

```erlang
decode_continue(term(), term()) -> {done, term(), binary()} | {more, term()} | {error, term()}
```

**Example**

```erlang
{ok, State} = avm_cbor:decode_start(<<16#82, 1, 2>>, []),
{done, [1, 2], <<>>} = avm_cbor:decode_continue(State, 100).
```

**What it does**

Returns done, more, or a controlled decode error after bounded parser transitions.

**What it is not**

It does not sleep, yield, or schedule the next call for the caller.

### `decode_all/1`

Decode a complete CBOR sequence using default options.

**Spec**

```erlang
decode_all(term()) -> {ok, list()} | {error, term()}
```

**Example**

```erlang
{ok, [1, 2]} = avm_cbor:decode_all(<<1, 2>>).
```

**What it does**

Consumes all CBOR items and succeeds only when no trailing data remains.

**What it is not**

It is not meant for incomplete stream buffers; use decode_sequence/1 for that.

### `decode_all/2`

Decode a complete CBOR sequence using explicit options.

**Spec**

```erlang
decode_all(term(), term()) -> {ok, list()} | {error, term()}
```

**Example**

```erlang
{ok, [1, 2]} = avm_cbor:decode_all(<<1, 2>>, [{max_items, 2}]).
```

**What it does**

Consumes all CBOR items while applying caller-provided limits and feature flags.

**What it is not**

It does not accept malformed or incomplete trailing data.

### `decode_sequence/1`

Decode as many complete CBOR items as possible using default options.

**Spec**

```erlang
decode_sequence(term()) -> {ok, list(), binary()} | {error, term()}
```

**Example**

```erlang
{ok, [1], <<16#82, 2>>} = avm_cbor:decode_sequence(<<1, 16#82, 2>>).
```

**What it does**

Returns complete items and keeps a truncated final item as Rest.

**What it is not**

It is not a whole-input validation helper; use decode_all/1 for that.

### `decode_sequence/2`

Decode as many complete CBOR items as possible using explicit options.

**Spec**

```erlang
decode_sequence(term(), term()) -> {ok, list(), binary()} | {error, term()}
```

**Example**

```erlang
{ok, [1, 2], <<>>} = avm_cbor:decode_sequence(<<1, 2>>, [{max_items, 2}]).
```

**What it does**

Like decode_sequence/1, but applies caller-provided limits and feature flags.

**What it is not**

It does not hide malformed data; malformed items still return errors.

### `sequence_fold/3`

Fold complete CBOR sequence items without building a result list.

**Spec**

```erlang
sequence_fold(term(), term(), term()) -> {ok, term(), binary()} | {error, term()}
```

**Example**

```erlang
Sum = fun(Item, Acc) -> {cont, Item + Acc} end,
{ok, 6, <<>>} = avm_cbor:sequence_fold(<<1, 2, 3>>, Sum, 0).
```

**What it does**

Calls Fun(Item, Acc) for each complete item; {cont, NewAcc} continues, while {halt, Result} returns the result and unconsumed Rest.

**What it is not**

It is not a streaming-input API; a truncated final item is returned unchanged as Rest, and callback exceptions are not caught.

### `encode/1`

Encode one supported Erlang value using default options.

**Spec**

```erlang
encode(term()) -> encode_result()
```

**Example**

```erlang
{ok, <<16#82, 1, 2>>} = avm_cbor:encode([1, 2]).
```

**What it does**

Produces definite-length CBOR for the documented public term representation.

**What it is not**

It does not enable preferred or deterministic encoding unless requested with encode/2.

### `encode/2`

Encode one supported Erlang value using explicit options.

**Spec**

```erlang
encode(term(), list()) -> encode_result()
```

**Example**

```erlang
{ok, <<23>>} = avm_cbor:encode(23, [{preferred, true}]).
```

**What it does**

Supports preferred and deterministic serialization while enforcing caller-provided limits.

**What it is not**

It does not support arbitrary Erlang terms outside the documented representation.

### `encode_with_size/1`

Encode one value and return its exact byte size using default options.

**Spec**

```erlang
encode_with_size(term()) -> {ok, binary(), non_neg_integer()} | {error, term()}
```

**Example**

```erlang
{ok, <<16#82, 1, 2>>, 3} = avm_cbor:encode_with_size([1, 2]).
```

**What it does**

Returns {ok, Binary, Size}, where Size is measured from the binary produced by the single encode operation.

**What it is not**

It is not a separate sizing or preflight pass.

### `encode_with_size/2`

Encode one value and return its exact byte size using explicit options.

**Spec**

```erlang
encode_with_size(term(), term()) -> {ok, binary(), non_neg_integer()} | {error, term()}
```

**Example**

```erlang
{ok, <<23>>, 1} = avm_cbor:encode_with_size(23, [{preferred, true}]).
```

**What it does**

Applies the same normalized options and limits as encode/2, then returns {ok, Binary, Size}.

**What it is not**

It does not estimate a size or encode the value twice.

### `encode_sequence/1`

Encode a list of values as an RFC 8742 CBOR sequence using default options.

**Spec**

```erlang
encode_sequence(term()) -> {ok, binary()} | {error, term()}
```

**Example**

```erlang
{ok, <<1, 2, 3>>} = avm_cbor:encode_sequence([1, 2, 3]).
```

**What it does**

Encodes each list element as one CBOR data item and concatenates the item binaries while enforcing sequence limits.

**What it is not**

It does not encode the input list as a CBOR array.

### `encode_sequence/2`

Encode a list of values as an RFC 8742 CBOR sequence using explicit options.

**Spec**

```erlang
encode_sequence(term(), term()) -> {ok, binary()} | {error, term()}
```

**Example**

```erlang
{ok, <<1, 2>>} = avm_cbor:encode_sequence([1, 2], [{max_items, 2}]).
```

**What it does**

Applies the supplied encoding options to every item and enforces cumulative max_items and max_bytes limits.

**What it is not**

It does not accept a non-list or improper list as a sequence.

### `validate_all/1`

Validate exactly one complete CBOR item using default partial-decoding limits.

**Spec**

```erlang
validate_all(term()) -> ok | {error, term()}
```

**Example**

```erlang
ok = avm_cbor:validate_all(<<16#82, 1, 2>>).
```

**What it does**

Checks the entire item and returns ok only when no trailing bytes remain, without materializing its nested Erlang value.

**What it is not**

It is not a CBOR sequence validator; additional complete items are reported as trailing bytes.

### `validate_all/2`

Validate exactly one complete CBOR item using explicit options.

**Spec**

```erlang
validate_all(term(), term()) -> ok | {error, term()}
```

**Example**

```erlang
ok = avm_cbor:validate_all(<<23>>, [{preferred, true}]).
```

**What it does**

Applies partial-decoding limits plus deterministic or preferred checks and rejects trailing bytes.

**What it is not**

It does not return the decoded value; use decode_all/2 when the materialized term is required.

### `partial_decode/1`

Validate and measure one CBOR item without eagerly constructing nested terms.

**Spec**

```erlang
partial_decode(term()) -> {ok, term(), binary()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
array = avm_cbor:partial_type(Partial).
```

**What it does**

Returns an opaque descriptor and trailing bytes using constrained partial-path defaults.

**What it is not**

The descriptor layout is private; use the partial_* accessors.

### `partial_decode/2`

Partially decode one CBOR item using explicit options.

**Spec**

```erlang
partial_decode(term(), term()) -> {ok, term(), binary()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#81, 1>>, [{max_depth, 2}]),
array = avm_cbor:partial_type(Partial).
```

**What it does**

Applies decode limits, deterministic/preferred checks, and the partial max_string_size limit.

**What it is not**

It does not bypass validation simply because nested terms are deferred.

### `partial_value_bytes/1`

Return the complete encoded bytes represented by a partial descriptor.

**Spec**

```erlang
partial_value_bytes(term()) -> binary() | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
<<16#82, 1, 2>> = avm_cbor:partial_value_bytes(Partial).
```

**What it does**

Returns the validated item as a sub-binary.

**What it is not**

It does not return only the child contents; use partial_contents/1 for that.

### `partial_deep_decode/1`

Materialize the value represented by a partial descriptor.

**Spec**

```erlang
partial_deep_decode(term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
{ok, [1, 2]} = avm_cbor:partial_deep_decode(Partial).
```

**What it does**

Fully decodes the validated item only when the caller needs it.

**What it is not**

It does not accept forged or malformed descriptors.

### `partial_skip/1`

Discard a validated partial descriptor.

**Spec**

```erlang
partial_skip(term()) -> ok | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
ok = avm_cbor:partial_skip(Partial).
```

**What it does**

Returns ok after validating that the value is a descriptor.

**What it is not**

It does not scan or materialize the represented value again.

### `partial_type/1`

Return the CBOR category represented by a partial descriptor.

**Spec**

```erlang
partial_type(term()) -> atom() | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
array = avm_cbor:partial_type(Partial).
```

**What it does**

Reports unsigned, negative, bytes, text, array, map, tag, float, or simple.

**What it is not**

It does not return an Erlang runtime type.

### `partial_count/1`

Return an array item count or map pair count.

**Spec**

```erlang
partial_count(term()) -> non_neg_integer() | undefined | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#A1, 1, 2>>),
1 = avm_cbor:partial_count(Partial).
```

**What it does**

Returns undefined for descriptor types without a count.

**What it is not**

It does not count nested descendants.

### `partial_tag/1`

Return the semantic tag number from a tag descriptor.

**Spec**

```erlang
partial_tag(term()) -> non_neg_integer() | undefined | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#C1, 1>>),
1 = avm_cbor:partial_tag(Partial).
```

**What it does**

Returns undefined for non-tag descriptors.

**What it is not**

It does not interpret tag semantics.

### `partial_size/1`

Return the content size of a byte or text string descriptor.

**Spec**

```erlang
partial_size(term()) -> non_neg_integer() | undefined | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#62, "ok">>),
2 = avm_cbor:partial_size(Partial).
```

**What it does**

Reports the content byte length and returns undefined for other descriptor types.

**What it is not**

It does not report the complete encoded item length.

### `partial_offset/1`

Return the descriptor item offset.

**Spec**

```erlang
partial_offset(term()) -> non_neg_integer() | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
0 = avm_cbor:partial_offset(Partial).
```

**What it does**

Reports the start offset recorded for the represented item.

**What it is not**

It does not return a child index.

### `partial_length/1`

Return the complete encoded length of a descriptor item.

**Spec**

```erlang
partial_length(term()) -> non_neg_integer() | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
3 = avm_cbor:partial_length(Partial).
```

**What it does**

Includes the CBOR header and any break marker.

**What it is not**

It does not return only string content length.

### `partial_contents/1`

Return encoded child bytes for an array, map, or tag.

**Spec**

```erlang
partial_contents(term()) -> {ok, binary()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
{ok, <<1, 2>>} = avm_cbor:partial_contents(Partial).
```

**What it does**

The returned binary can be walked with repeated partial_decode calls.

**What it is not**

It does not deep-decode the children.

### `partial_map_fold/3`

Fold a map descriptor as opaque key and value descriptors.

**Spec**

```erlang
partial_map_fold(term(), fun((term(), term(), term()) -> {cont, term()} | {halt, term()}), term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#A1, 1, 2>>),
Count = fun(_Key, _Value, Acc) -> {cont, Acc + 1} end,
{ok, 1} = avm_cbor:partial_map_fold(Partial, Count, 0).
```

**What it does**

Calls Fun(KeyDescriptor, ValueDescriptor, Acc) in CBOR map order; {cont, NewAcc} continues and {halt, Result} stops early.

**What it is not**

It does not materialize the map or catch callback exceptions.

### `partial_array_fold/3`

Fold an array descriptor as opaque element descriptors.

**Spec**

```erlang
partial_array_fold(term(), fun((term(), term()) -> {cont, term()} | {halt, term()}), term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
Sum = fun(Element, Acc) ->
    {ok, Value} = avm_cbor:partial_deep_decode(Element),
    {cont, Acc + Value}
end,
{ok, 3} = avm_cbor:partial_array_fold(Partial, Sum, 0).
```

**What it does**

Calls Fun(ElementDescriptor, Acc) in array order with the same continue and early-halt contract as partial_map_fold/3.

**What it is not**

It does not materialize the array or accept a non-array descriptor.

### `partial_select/2`

Select requested keys from a map descriptor in one pass.

**Spec**

```erlang
partial_select(term(), term()) -> {ok, [{term(), term()}], [term()]} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#A2, 1, 2, 3, 4>>),
{ok, [{1, Value}], [9]} = avm_cbor:partial_select(Partial, [1, 9]),
{ok, 2} = avm_cbor:partial_deep_decode(Value).
```

**What it does**

Returns {ok, Found, Missing}; found pairs retain CBOR map order, missing keys retain request order, and values remain descriptors.

**What it is not**

It does not accept duplicate requested keys or deep-decode selected values; the first matching map entry wins.

### `partial_map_find/2`

Find the first matching key in a map descriptor.

**Spec**

```erlang
partial_map_find(term(), term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#A1, 1, 2>>),
{ok, Value} = avm_cbor:partial_map_find(Partial, 1),
{ok, 2} = avm_cbor:partial_deep_decode(Value).
```

**What it does**

Compares decoded keys exactly and returns the matching opaque value descriptor without decoding that value.

**What it is not**

It does not return a materialized value or search past the first match.

### `partial_array_nth/2`

Return an opaque array element descriptor by zero-based index.

**Spec**

```erlang
partial_array_nth(term(), term()) -> {ok, term()} | {error, term()}
```

**Example**

```erlang
{ok, Partial, <<>>} = avm_cbor:partial_decode(<<16#82, 1, 2>>),
{ok, Second} = avm_cbor:partial_array_nth(Partial, 1),
{ok, 2} = avm_cbor:partial_deep_decode(Second).
```

**What it does**

Traverses the array until the requested non-negative index and returns that element descriptor.

**What it is not**

It is not one-based and does not deep-decode the selected element.

### `get/2`

Look up a key in a decoded CBOR map.

**Spec**

```erlang
get(term(), {map, list()}) -> {ok, term()} | error
```

**Example**

```erlang
Map = {map, [{{text, <<"id">>}, 7}]},
{ok, 7} = avm_cbor:get({text, <<"id">>}, Map).
```

**What it does**

Searches the {map, Pairs} representation and returns {ok, Value} when present.

**What it is not**

It is not an Erlang map helper; decoded CBOR maps are represented as pair lists.

### `get/3`

Look up a key in a decoded CBOR map with a default.

**Spec**

```erlang
get(term(), {map, list()}, term()) -> term()
```

**Example**

```erlang
Map = {map, []},
unknown = avm_cbor:get({text, <<"id">>}, Map, unknown).
```

**What it does**

Returns the value when present, otherwise returns the supplied default.

**What it is not**

It does not distinguish a missing key from a present value equal to the default.

### `require/2`

Require a key in a decoded CBOR map.

**Spec**

```erlang
require(term(), {map, list()}) -> {ok, term()} | {error, {missing_key, term()}}
```

**Example**

```erlang
Map = {map, [{{text, <<"id">>}, 7}]},
{ok, 7} = avm_cbor:require({text, <<"id">>}, Map).
```

**What it does**

Returns a structured missing-key error when the key is absent.

**What it is not**

It does not validate the value type; use as_text/1, as_int/1, or related helpers.

### `as_text/1`

Extract a decoded CBOR text string.

**Spec**

```erlang
as_text(term()) -> {ok, binary()} | {error, bad_type}
```

**Example**

```erlang
{ok, <<"hello">>} = avm_cbor:as_text({text, <<"hello">>}).
```

**What it does**

Accepts {text, Bin} and returns the UTF-8 binary.

**What it is not**

It does not accept arbitrary binaries; use as_bytes/1 for byte strings.

### `as_bytes/1`

Extract a decoded CBOR byte string.

**Spec**

```erlang
as_bytes(term()) -> {ok, binary()} | {error, bad_type}
```

**Example**

```erlang
{ok, <<1, 2>>} = avm_cbor:as_bytes(<<1, 2>>).
```

**What it does**

Accepts a binary byte string and returns it unchanged.

**What it is not**

It does not accept {text, Bin}; text and byte strings are distinct.

### `as_int/1`

Extract a decoded CBOR integer.

**Spec**

```erlang
as_int(term()) -> {ok, integer()} | {error, bad_type}
```

**Example**

```erlang
{ok, 42} = avm_cbor:as_int(42).
```

**What it does**

Accepts Erlang integers returned by the decoder.

**What it is not**

It does not coerce floats, strings, or binaries into integers.

### `as_bool/1`

Extract a decoded CBOR boolean.

**Spec**

```erlang
as_bool(term()) -> {ok, boolean()} | {error, bad_type}
```

**Example**

```erlang
{ok, true} = avm_cbor:as_bool(true).
```

**What it does**

Accepts only true or false.

**What it is not**

It does not treat other values as truthy or falsey.

### `ble_options/0`

Return strict options for small BLE-oriented payloads.

**Spec**

```erlang
ble_options() -> list()
```

**Example**

```erlang
Options = avm_cbor:ble_options(),
{max_depth, 8} = lists:keyfind(max_depth, 1, Options).
```

**What it does**

Provides conservative depth, item, byte, and string limits with floats, tags, and indefinite-length items disabled.

**What it is not**

It is not a Bluetooth transport implementation or a performance benchmark.
