aws/internal/codec/xml
XML encoder helpers for restXml / awsQuery / ec2Query bodies.
Minimum viable: element-per-member, text-content for primitives,
proper escaping of <>&"'. Honours @xmlName overrides at the
call site (the emitter passes the resolved element name).
The XML response decoder lives in
src/aws/internal/codec/xml_decode.gleam — kept separate because
it pulls in xmerl via FFI, which is heavier than the pure-string
encoder side.
Values
pub fn blob_text(b: BitArray) -> String
Base64-encode a blob value for XML body inclusion. S3 uses base64 for binary fields inside XML bodies (Content-MD5, ChecksumSHA256).
pub fn element(name: String, inner: String) -> String
<Name>...</Name> wrapper around inner content.
pub fn element_with_attrs(
name: String,
attrs: List(#(String, String)),
inner: String,
) -> String
<Name attr1="v1" attr2="v2">inner</Name>. Attribute values are
escaped the same way as text content; attribute names are passed
verbatim and assumed to be safe (Smithy member names).
pub fn empty_element(name: String) -> String
<Name/> — short form for empty elements.
pub fn escape_attr(s: String) -> String
Escape &, <, >, ", and ' in attribute values. AWS
service XML is double-quoted, so ' doesn’t strictly need
escaping, but the entity is harmless and keeps the encoder
quote-style agnostic.
pub fn flat_list(
member_name: String,
entries: List(String),
) -> String
Same as list_element but for @xmlFlattened lists — no
wrapper element; entries become direct siblings.
pub fn flat_list_ns(
member_name: String,
member_attrs: List(#(String, String)),
entries: List(String),
) -> String
flat_list variant with namespace attributes on every emitted
member element. Empty member_attrs collapses to a bare element.
pub fn flat_map(
member_name: String,
key_name: String,
value_name: String,
entries: dict.Dict(String, String),
) -> String
@xmlFlattened map: each entry becomes a top-level
<member_name><key>K</key><value>V</value></member_name> block
— no outer wrapper, no <entry> tag. The caller’s containing
element provides the sequencing. value_name is the key / value
inner-element name ("key" / "value" by default; @xmlName
overrides land in the caller).
pub fn flat_map_ns(
member_name: String,
member_attrs: List(#(String, String)),
key_name: String,
key_attrs: List(#(String, String)),
value_name: String,
value_attrs: List(#(String, String)),
entries: dict.Dict(String, String),
) -> String
flat_map variant with namespace attributes on the repeated
member wrappers and on the key / value wrappers inside.
pub fn float_text(f: Float) -> String
pub fn list_element(
wrapper: String,
member_name: String,
entries: List(String),
) -> String
Build a list element with each entry as <member_name>value</member_name>
children. The wrapper element comes from the list shape’s name; the
per-entry element name comes from the list member’s @xmlName (the
emitter passes both).
pub fn list_element_ns(
wrapper: String,
wrapper_attrs: List(#(String, String)),
member_name: String,
member_attrs: List(#(String, String)),
entries: List(String),
) -> String
list_element variant that carries member-level XML namespace
attributes. wrapper_attrs go on the outer wrapping element;
member_attrs go on every per-entry wrapping. Either list may
be empty, in which case the corresponding wrapper renders
without attributes — equivalent to list_element in that case.
pub fn map_element(
wrapper: String,
key_name: String,
value_name: String,
entries: dict.Dict(String, String),
) -> String
Build a map element: each entry becomes <entry><key>K</key><value>V</value></entry>
inside a wrapper. Smithy default uses entry / key / value —
@xmlName overrides land in the caller.
pub fn map_element_ns(
wrapper: String,
wrapper_attrs: List(#(String, String)),
key_name: String,
key_attrs: List(#(String, String)),
value_name: String,
value_attrs: List(#(String, String)),
entries: dict.Dict(String, String),
) -> String
map_element variant with namespace attributes on the outer
wrapper plus the key / value wrappers. The intermediate
<entry> wrapper is unattributed (Smithy doesn’t expose a
trait for it).
pub fn map_entries(
key_name: String,
value_name: String,
entries: dict.Dict(String, String),
) -> String
Just the <entry>...</entry> siblings of a map, no wrapper.
Used for nested maps — the outer map’s <value> element wraps
the inner map’s entries directly.
pub fn map_entries_ns(
key_name: String,
key_attrs: List(#(String, String)),
value_name: String,
value_attrs: List(#(String, String)),
entries: dict.Dict(String, String),
) -> String
map_entries variant with namespace attributes on the key /
value wrappers. Used for nested maps and as the body of
map_element_ns.