-module(aws@internal@codec@xml). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/aws/internal/codec/xml.gleam"). -export([element/2, escape_text/1, escape_attr/1, element_with_attrs/3, empty_element/1, text/1, bool_text/1, int_text/1, float_text/1, blob_text/1, list_element/3, flat_list/2, map_entries/3, map_element/4, flat_map/4, list_element_ns/5, flat_list_ns/3, map_entries_ns/5, map_element_ns/7, flat_map_ns/7]). -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( " XML encoder helpers for restXml / awsQuery / ec2Query bodies.\n" " Minimum viable: element-per-member, text-content for primitives,\n" " proper escaping of `<>&\"'`. Honours `@xmlName` overrides at the\n" " call site (the emitter passes the resolved element name).\n" "\n" " The XML response decoder lives in\n" " `src/aws/internal/codec/xml_decode.gleam` — kept separate because\n" " it pulls in xmerl via FFI, which is heavier than the pure-string\n" " encoder side.\n" ). -file("src/aws/internal/codec/xml.gleam", 17). ?DOC(" `...` wrapper around inner content.\n"). -spec element(binary(), binary()) -> binary(). element(Name, Inner) -> <<<<<<<<<<<<"<"/utf8, Name/binary>>/binary, ">"/utf8>>/binary, Inner/binary>>/binary, ">/binary, Name/binary>>/binary, ">"/utf8>>. -file("src/aws/internal/codec/xml.gleam", 50). ?DOC(" Escape `<`, `>`, `&` in element text content.\n"). -spec escape_text(binary()) -> binary(). escape_text(S) -> _pipe = S, _pipe@1 = gleam@string:replace(_pipe, <<"&"/utf8>>, <<"&"/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<"<"/utf8>>, <<"<"/utf8>>), gleam@string:replace(_pipe@2, <<">"/utf8>>, <<">"/utf8>>). -file("src/aws/internal/codec/xml.gleam", 61). ?DOC( " Escape `&`, `<`, `>`, `\"`, and `'` in attribute values. AWS\n" " service XML is double-quoted, so `'` doesn't strictly need\n" " escaping, but the entity is harmless and keeps the encoder\n" " quote-style agnostic.\n" ). -spec escape_attr(binary()) -> binary(). escape_attr(S) -> _pipe = S, _pipe@1 = escape_text(_pipe), _pipe@2 = gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"""/utf8>>), gleam@string:replace(_pipe@2, <<"'"/utf8>>, <<"'"/utf8>>). -file("src/aws/internal/codec/xml.gleam", 24). ?DOC( " `inner`. Attribute values are\n" " escaped the same way as text content; attribute names are passed\n" " verbatim and assumed to be safe (Smithy member names).\n" ). -spec element_with_attrs(binary(), list({binary(), binary()}), binary()) -> binary(). element_with_attrs(Name, Attrs, Inner) -> Attr_str = case Attrs of [] -> <<""/utf8>>; _ -> gleam@list:fold( Attrs, <<""/utf8>>, fun(Acc, P) -> {K, V} = P, <<<<<<<<<>/binary, K/binary>>/binary, "=\""/utf8>>/binary, (escape_attr(V))/binary>>/binary, "\""/utf8>> end ) end, <<<<<<<<<<<<<<"<"/utf8, Name/binary>>/binary, Attr_str/binary>>/binary, ">"/utf8>>/binary, Inner/binary>>/binary, ">/binary, Name/binary>>/binary, ">"/utf8>>. -file("src/aws/internal/codec/xml.gleam", 41). ?DOC(" `` — short form for empty elements.\n"). -spec empty_element(binary()) -> binary(). empty_element(Name) -> <<<<"<"/utf8, Name/binary>>/binary, "/>"/utf8>>. -file("src/aws/internal/codec/xml.gleam", 45). -spec text(binary()) -> binary(). text(Value) -> escape_text(Value). -file("src/aws/internal/codec/xml.gleam", 69). ?DOC(" Format helpers for primitive members.\n"). -spec bool_text(boolean()) -> binary(). bool_text(B) -> case B of true -> <<"true"/utf8>>; false -> <<"false"/utf8>> end. -file("src/aws/internal/codec/xml.gleam", 77). -spec int_text(integer()) -> binary(). int_text(N) -> erlang:integer_to_binary(N). -file("src/aws/internal/codec/xml.gleam", 80). -spec float_text(float()) -> binary(). float_text(F) -> aws_ffi:float_short(F). -file("src/aws/internal/codec/xml.gleam", 84). ?DOC( " Base64-encode a blob value for XML body inclusion. S3 uses base64\n" " for binary fields inside XML bodies (Content-MD5, ChecksumSHA256).\n" ). -spec blob_text(bitstring()) -> binary(). blob_text(B) -> gleam_stdlib:base64_encode(B, true). -file("src/aws/internal/codec/xml.gleam", 92). ?DOC( " Build a list element with each entry as `value`\n" " children. The wrapper element comes from the list shape's name; the\n" " per-entry element name comes from the list member's `@xmlName` (the\n" " emitter passes both).\n" ). -spec list_element(binary(), binary(), list(binary())) -> binary(). list_element(Wrapper, Member_name, Entries) -> Inner = gleam@list:fold( Entries, <<""/utf8>>, fun(Acc, Entry_inner) -> <> end ), element(Wrapper, Inner). -file("src/aws/internal/codec/xml.gleam", 106). ?DOC( " Same as `list_element` but for `@xmlFlattened` lists — no\n" " wrapper element; entries become direct siblings.\n" ). -spec flat_list(binary(), list(binary())) -> binary(). flat_list(Member_name, Entries) -> gleam@list:fold( Entries, <<""/utf8>>, fun(Acc, Entry_inner) -> <> end ). -file("src/aws/internal/codec/xml.gleam", 127). ?DOC( " Just the `...` siblings of a map, no wrapper.\n" " Used for nested maps — the outer map's `` element wraps\n" " the inner map's entries directly.\n" ). -spec map_entries(binary(), binary(), gleam@dict:dict(binary(), binary())) -> binary(). map_entries(Key_name, Value_name, Entries) -> gleam@dict:fold( Entries, <<""/utf8>>, fun(Acc, K, V) -> <>, <<(element(Key_name, escape_text(K)))/binary, (element(Value_name, V))/binary>> ))/binary>> end ). -file("src/aws/internal/codec/xml.gleam", 115). ?DOC( " Build a map element: each entry becomes `KV`\n" " inside a wrapper. Smithy default uses `entry` / `key` / `value` —\n" " `@xmlName` overrides land in the caller.\n" ). -spec map_element( binary(), binary(), binary(), gleam@dict:dict(binary(), binary()) ) -> binary(). map_element(Wrapper, Key_name, Value_name, Entries) -> element(Wrapper, map_entries(Key_name, Value_name, Entries)). -file("src/aws/internal/codec/xml.gleam", 147). ?DOC( " `@xmlFlattened` map: each entry becomes a top-level\n" " `KV` block\n" " — no outer wrapper, no `` tag. The caller's containing\n" " element provides the sequencing. `value_name` is the key / value\n" " inner-element name (`\"key\"` / `\"value\"` by default; `@xmlName`\n" " overrides land in the caller).\n" ). -spec flat_map( binary(), binary(), binary(), gleam@dict:dict(binary(), binary()) ) -> binary(). flat_map(Member_name, Key_name, Value_name, Entries) -> gleam@dict:fold( Entries, <<""/utf8>>, fun(Acc, K, V) -> <> ))/binary>> end ). -file("src/aws/internal/codec/xml.gleam", 167). ?DOC( " `list_element` variant that carries member-level XML namespace\n" " attributes. `wrapper_attrs` go on the outer wrapping element;\n" " `member_attrs` go on every per-entry wrapping. Either list may\n" " be empty, in which case the corresponding wrapper renders\n" " without attributes — equivalent to `list_element` in that case.\n" ). -spec list_element_ns( binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), list(binary()) ) -> binary(). list_element_ns(Wrapper, Wrapper_attrs, Member_name, Member_attrs, Entries) -> Inner = gleam@list:fold( Entries, <<""/utf8>>, fun(Acc, Entry_inner) -> <> end ), element_with_attrs(Wrapper, Wrapper_attrs, Inner). -file("src/aws/internal/codec/xml.gleam", 183). ?DOC( " `flat_list` variant with namespace attributes on every emitted\n" " member element. Empty `member_attrs` collapses to a bare element.\n" ). -spec flat_list_ns(binary(), list({binary(), binary()}), list(binary())) -> binary(). flat_list_ns(Member_name, Member_attrs, Entries) -> gleam@list:fold( Entries, <<""/utf8>>, fun(Acc, Entry_inner) -> <> end ). -file("src/aws/internal/codec/xml.gleam", 216). ?DOC( " `map_entries` variant with namespace attributes on the key /\n" " value wrappers. Used for nested maps and as the body of\n" " `map_element_ns`.\n" ). -spec map_entries_ns( binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), gleam@dict:dict(binary(), binary()) ) -> binary(). map_entries_ns(Key_name, Key_attrs, Value_name, Value_attrs, Entries) -> gleam@dict:fold( Entries, <<""/utf8>>, fun(Acc, K, V) -> <>, <<(element_with_attrs(Key_name, Key_attrs, escape_text(K)))/binary, (element_with_attrs(Value_name, Value_attrs, V))/binary>> ))/binary>> end ). -file("src/aws/internal/codec/xml.gleam", 197). ?DOC( " `map_element` variant with namespace attributes on the outer\n" " wrapper plus the key / value wrappers. The intermediate\n" " `` wrapper is unattributed (Smithy doesn't expose a\n" " trait for it).\n" ). -spec map_element_ns( binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), gleam@dict:dict(binary(), binary()) ) -> binary(). map_element_ns( Wrapper, Wrapper_attrs, Key_name, Key_attrs, Value_name, Value_attrs, Entries ) -> element_with_attrs( Wrapper, Wrapper_attrs, map_entries_ns(Key_name, Key_attrs, Value_name, Value_attrs, Entries) ). -file("src/aws/internal/codec/xml.gleam", 235). ?DOC( " `flat_map` variant with namespace attributes on the repeated\n" " member wrappers and on the key / value wrappers inside.\n" ). -spec flat_map_ns( binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), binary(), list({binary(), binary()}), gleam@dict:dict(binary(), binary()) ) -> binary(). flat_map_ns( Member_name, Member_attrs, Key_name, Key_attrs, Value_name, Value_attrs, Entries ) -> gleam@dict:fold( Entries, <<""/utf8>>, fun(Acc, K, V) -> <> ))/binary>> end ).