Packages
toon_codec
1.0.0
TOON (Token-Oriented Object Notation) encoder/decoder - a compact, token-efficient format for LLM input
Current section
Files
Jump to
Current section
Files
src/toon_codec@encode@arrays.erl
-module(toon_codec@encode@arrays).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/toon_codec/encode/arrays.gleam").
-export([encode_array/5]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Array encoding functions.\n"
"\n"
" This module handles encoding of JSON arrays to TOON format, including:\n"
" - Inline primitive arrays\n"
" - Tabular arrays (uniform objects)\n"
" - Arrays of arrays\n"
" - Mixed/complex arrays (expanded list form)\n"
" Encode an array to TOON format.\n"
"\n"
" Automatically detects the best representation:\n"
" - Empty arrays: `key[0]:`\n"
" - Primitive arrays: inline format `key[N]: v1,v2,v3`\n"
" - Arrays of primitive arrays: expanded list with inline subarrays\n"
" - Uniform objects with primitive values: tabular format\n"
" - Mixed/complex: expanded list format\n"
"\n"
" ## Arguments\n"
"\n"
" * `key` - Optional key name (None for root arrays)\n"
" * `values` - The array elements\n"
" * `writer` - The line writer\n"
" * `depth` - Current indentation depth\n"
" * `options` - Encoding options\n"
" Encode a primitive array in inline format.\n"
"\n"
" ## Examples\n"
"\n"
" ```\n"
" tags[3]: admin,ops,dev\n"
" ```\n"
" Encode an array of primitive arrays in expanded list format.\n"
"\n"
" ## Examples\n"
"\n"
" ```\n"
" pairs[2]:\n"
" - [2]: 1,2\n"
" - [2]: 3,4\n"
" ```\n"
" Encode an array of uniform objects in tabular format.\n"
"\n"
" ## Examples\n"
"\n"
" ```\n"
" users[2]{id,name}:\n"
" 1,Alice\n"
" 2,Bob\n"
" ```\n"
" Encode a mixed/complex array in expanded list format.\n"
"\n"
" ## Examples\n"
"\n"
" ```\n"
" items[3]:\n"
" - 1\n"
" - a: 1\n"
" - text\n"
" ```\n"
" Encode a single list item (element in expanded array).\n"
" Encode a complex array as a list item.\n"
" Encode an object as a list item.\n"
"\n"
" The first field appears on the hyphen line, remaining fields at depth + 1.\n"
" Encode the first field of an object on the hyphen line.\n"
" Encode object fields (helper for encoding remaining fields).\n"
" Encode a key-value pair at a specific depth.\n"
).
-file("src/toon_codec/encode/arrays.gleam", 95).
-spec encode_empty_array(
gleam@option:option(binary()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_empty_array(Key, Writer, Depth, Options) ->
Header = toon_codec@encode@primitives:format_header(
0,
Key,
erlang:element(3, Options),
erlang:element(4, Options)
),
toon_codec@encode@writer:push(Writer, Depth, Header).
-file("src/toon_codec/encode/arrays.gleam", 136).
-spec encode_primitive_array(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_primitive_array(Key, Values, Writer, Depth, Options) ->
Length = erlang:length(Values),
Header = toon_codec@encode@primitives:format_header(
Length,
Key,
erlang:element(3, Options),
erlang:element(4, Options)
),
Values_str = toon_codec@encode@primitives:encode_and_join_primitives(
Values,
erlang:element(3, Options)
),
Line = <<<<Header/binary, " "/utf8>>/binary, Values_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line).
-file("src/toon_codec/encode/arrays.gleam", 159).
-spec encode_array_of_arrays(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_array_of_arrays(Key, Values, Writer, Depth, Options) ->
Length = erlang:length(Values),
Header = toon_codec@encode@primitives:format_header(
Length,
Key,
erlang:element(3, Options),
erlang:element(4, Options)
),
Writer@1 = toon_codec@encode@writer:push(Writer, Depth, Header),
gleam@list:fold(Values, Writer@1, fun(W, Item) -> case Item of
{array, Inner_items} ->
Inner_length = erlang:length(Inner_items),
Inner_header = toon_codec@encode@primitives:format_header(
Inner_length,
none,
erlang:element(3, Options),
erlang:element(4, Options)
),
Inner_values_str = toon_codec@encode@primitives:encode_and_join_primitives(
Inner_items,
erlang:element(3, Options)
),
Line = <<<<<<(<<"- "/utf8>>)/binary, Inner_header/binary>>/binary,
" "/utf8>>/binary,
Inner_values_str/binary>>,
toon_codec@encode@writer:push(W, Depth + 1, Line);
_ ->
W
end end).
-file("src/toon_codec/encode/arrays.gleam", 203).
-spec encode_tabular_array(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
list(binary()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_tabular_array(Key, Values, Fields, Writer, Depth, Options) ->
Length = erlang:length(Values),
Header = toon_codec@encode@primitives:format_tabular_header(
Length,
Key,
Fields,
erlang:element(3, Options),
erlang:element(4, Options)
),
Writer@1 = toon_codec@encode@writer:push(Writer, Depth, Header),
gleam@list:fold(
Values,
Writer@1,
fun(W, Obj) ->
Field_values = toon_codec@encode@internal:extract_field_values(
Obj,
Fields
),
Row = toon_codec@encode@primitives:encode_and_join_primitives(
Field_values,
erlang:element(3, Options)
),
toon_codec@encode@writer:push(W, Depth + 1, Row)
end
).
-file("src/toon_codec/encode/arrays.gleam", 304).
-spec encode_complex_array_item(
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_complex_array_item(Items, Writer, Depth, Options) ->
Writer@1 = toon_codec@encode@writer:push(Writer, Depth, <<"-"/utf8>>),
encode_array(none, Items, Writer@1, Depth + 1, Options).
-file("src/toon_codec/encode/arrays.gleam", 80).
-spec encode_array(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_array(Key, Values, Writer, Depth, Options) ->
case Values of
[] ->
encode_empty_array(Key, Writer, Depth, Options);
_ ->
detect_and_encode_array(Key, Values, Writer, Depth, Options)
end.
-file("src/toon_codec/encode/arrays.gleam", 108).
-spec detect_and_encode_array(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
detect_and_encode_array(Key, Values, Writer, Depth, Options) ->
case toon_codec@encode@internal:is_array_of_primitives(Values) of
true ->
encode_primitive_array(Key, Values, Writer, Depth, Options);
false ->
case toon_codec@encode@internal:is_array_of_arrays(Values) of
true ->
case toon_codec@encode@internal:all_arrays_of_primitives(
Values
) of
true ->
encode_array_of_arrays(
Key,
Values,
Writer,
Depth,
Options
);
false ->
encode_mixed_array(
Key,
Values,
Writer,
Depth,
Options
)
end;
false ->
case toon_codec@encode@internal:detect_tabular(Values) of
{some, Fields} ->
encode_tabular_array(
Key,
Values,
Fields,
Writer,
Depth,
Options
);
none ->
encode_mixed_array(
Key,
Values,
Writer,
Depth,
Options
)
end
end
end.
-file("src/toon_codec/encode/arrays.gleam", 235).
-spec encode_mixed_array(
gleam@option:option(binary()),
list(toon_codec@types:json_value()),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_mixed_array(Key, Values, Writer, Depth, Options) ->
Length = erlang:length(Values),
Header = toon_codec@encode@primitives:format_header(
Length,
Key,
erlang:element(3, Options),
erlang:element(4, Options)
),
Writer@1 = toon_codec@encode@writer:push(Writer, Depth, Header),
gleam@list:fold(
Values,
Writer@1,
fun(W, Item) -> encode_list_item(Item, W, Depth + 1, Options) end
).
-file("src/toon_codec/encode/arrays.gleam", 262).
-spec encode_list_item(
toon_codec@types:json_value(),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_list_item(Item, Writer, Depth, Options) ->
case Item of
null ->
Value_str = toon_codec@encode@primitives:encode_primitive(
Item,
erlang:element(3, Options)
),
Line = <<(<<"- "/utf8>>)/binary, Value_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{bool, _} ->
Value_str = toon_codec@encode@primitives:encode_primitive(
Item,
erlang:element(3, Options)
),
Line = <<(<<"- "/utf8>>)/binary, Value_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{number, _} ->
Value_str = toon_codec@encode@primitives:encode_primitive(
Item,
erlang:element(3, Options)
),
Line = <<(<<"- "/utf8>>)/binary, Value_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{string, _} ->
Value_str = toon_codec@encode@primitives:encode_primitive(
Item,
erlang:element(3, Options)
),
Line = <<(<<"- "/utf8>>)/binary, Value_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{array, Items} ->
case toon_codec@encode@internal:is_array_of_primitives(Items) of
true ->
Length = erlang:length(Items),
Header = toon_codec@encode@primitives:format_header(
Length,
none,
erlang:element(3, Options),
erlang:element(4, Options)
),
Values_str = toon_codec@encode@primitives:encode_and_join_primitives(
Items,
erlang:element(3, Options)
),
Line@1 = <<<<<<(<<"- "/utf8>>)/binary, Header/binary>>/binary,
" "/utf8>>/binary,
Values_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line@1);
false ->
encode_complex_array_item(Items, Writer, Depth, Options)
end;
{object, Fields} ->
encode_object_as_list_item(Fields, Writer, Depth, Options)
end.
-file("src/toon_codec/encode/arrays.gleam", 444).
-spec encode_key_value_at_depth(
binary(),
toon_codec@types:json_value(),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_key_value_at_depth(Key, Value, Writer, Depth, Options) ->
Encoded_key = toon_codec@encode@primitives:encode_key(Key),
case Value of
null ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<Encoded_key/binary, ": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{bool, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<Encoded_key/binary, ": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{number, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<Encoded_key/binary, ": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{string, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<Encoded_key/binary, ": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{array, Items} ->
encode_array({some, Key}, Items, Writer, Depth, Options);
{object, Nested_fields} ->
Writer@1 = toon_codec@encode@writer:push(
Writer,
Depth,
<<Encoded_key/binary, ":"/utf8>>
),
encode_object_fields(Nested_fields, Writer@1, Depth + 1, Options)
end.
-file("src/toon_codec/encode/arrays.gleam", 432).
-spec encode_object_fields(
list({binary(), toon_codec@types:json_value()}),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_object_fields(Fields, Writer, Depth, Options) ->
gleam@list:fold(
Fields,
Writer,
fun(W, Field) ->
{Key, Value} = Field,
encode_key_value_at_depth(Key, Value, W, Depth, Options)
end
).
-file("src/toon_codec/encode/arrays.gleam", 338).
-spec encode_first_field_on_hyphen(
{binary(), toon_codec@types:json_value()},
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_first_field_on_hyphen(Field, Writer, Depth, Options) ->
{Key, Value} = Field,
Encoded_key = toon_codec@encode@primitives:encode_key(Key),
case Value of
null ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<<<(<<"- "/utf8>>)/binary, Encoded_key/binary>>/binary,
": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{bool, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<<<(<<"- "/utf8>>)/binary, Encoded_key/binary>>/binary,
": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{number, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<<<(<<"- "/utf8>>)/binary, Encoded_key/binary>>/binary,
": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{string, _} ->
Encoded_value = toon_codec@encode@primitives:encode_primitive(
Value,
erlang:element(3, Options)
),
Line = <<<<<<(<<"- "/utf8>>)/binary, Encoded_key/binary>>/binary,
": "/utf8>>/binary,
Encoded_value/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line);
{array, Items} ->
case toon_codec@encode@internal:is_array_of_primitives(Items) of
true ->
Length = erlang:length(Items),
Header = toon_codec@encode@primitives:format_header(
Length,
{some, Key},
erlang:element(3, Options),
erlang:element(4, Options)
),
Values_str = toon_codec@encode@primitives:encode_and_join_primitives(
Items,
erlang:element(3, Options)
),
Line@1 = <<<<<<(<<"- "/utf8>>)/binary, Header/binary>>/binary,
" "/utf8>>/binary,
Values_str/binary>>,
toon_codec@encode@writer:push(Writer, Depth, Line@1);
false ->
case toon_codec@encode@internal:detect_tabular(Items) of
{some, Tab_fields} ->
Length@1 = erlang:length(Items),
Header@1 = toon_codec@encode@primitives:format_tabular_header(
Length@1,
{some, Key},
Tab_fields,
erlang:element(3, Options),
erlang:element(4, Options)
),
Line@2 = <<(<<"- "/utf8>>)/binary, Header@1/binary>>,
Writer@1 = toon_codec@encode@writer:push(
Writer,
Depth,
Line@2
),
gleam@list:fold(
Items,
Writer@1,
fun(W, Obj) ->
Field_values = toon_codec@encode@internal:extract_field_values(
Obj,
Tab_fields
),
Row = toon_codec@encode@primitives:encode_and_join_primitives(
Field_values,
erlang:element(3, Options)
),
toon_codec@encode@writer:push(
W,
Depth + 1,
Row
)
end
);
none ->
Length@2 = erlang:length(Items),
Header@2 = toon_codec@encode@primitives:format_header(
Length@2,
{some, Key},
erlang:element(3, Options),
erlang:element(4, Options)
),
Line@3 = <<(<<"- "/utf8>>)/binary, Header@2/binary>>,
Writer@2 = toon_codec@encode@writer:push(
Writer,
Depth,
Line@3
),
encode_array(
none,
Items,
Writer@2,
Depth + 1,
Options
)
end
end;
{object, Nested_fields} ->
Line@4 = <<<<(<<"- "/utf8>>)/binary, Encoded_key/binary>>/binary,
":"/utf8>>,
Writer@3 = toon_codec@encode@writer:push(Writer, Depth, Line@4),
encode_object_fields(Nested_fields, Writer@3, Depth + 2, Options)
end.
-file("src/toon_codec/encode/arrays.gleam", 316).
-spec encode_object_as_list_item(
list({binary(), toon_codec@types:json_value()}),
toon_codec@encode@writer:writer(),
integer(),
toon_codec@types:encode_options()
) -> toon_codec@encode@writer:writer().
encode_object_as_list_item(Fields, Writer, Depth, Options) ->
case Fields of
[] ->
toon_codec@encode@writer:push(Writer, Depth, <<"-"/utf8>>);
[First | Rest] ->
Writer@1 = encode_first_field_on_hyphen(
First,
Writer,
Depth,
Options
),
case Rest of
[] ->
Writer@1;
_ ->
encode_object_fields(Rest, Writer@1, Depth + 1, Options)
end
end.