/// Parsing of Dictionaries (RFC 9651 ยง4.2.2) and the public
/// `parse_dictionary` entry points.
///
/// Members are `key=value` pairs separated by `","` with surrounding OWS.
/// A member without `=value` is a Boolean true Item with its own
/// parameters. Duplicate keys collapse to their last occurrence.
///|
/// Parses a Dictionary.
pub fn parse_dictionary_cursor(
cursor : Cursor,
limits : ParseLimits,
) -> Result[SfDictionary, SfError] {
let dict = SfDictionary::new()
while !cursor.is_end() {
let key = match parse_key(cursor) {
Err(e) => return Err(e)
Ok(k) => k
}
let dict_member = if cursor.peek() == Some(b'=') {
let _ = cursor.consume()
match parse_item_or_inner_list_cursor(cursor, limits) {
Err(e) => return Err(e)
Ok(v) => v
}
} else {
let parameters = match parse_parameters_cursor(cursor, limits) {
Err(e) => return Err(e)
Ok(v) => v
}
ItemMember({ bare: Boolean(true), parameters })
}
dict.set(key, dict_member)
if dict.len() > limits.max_members {
return Err(err_at(cursor, TooManyMembers))
}
cursor.skip_ows()
if cursor.is_end() {
break
}
if !cursor.consume_if(b',') {
return Err(err_at(cursor, TrailingInput))
}
cursor.skip_ows()
if cursor.is_end() {
return Err(err_at(cursor, TrailingInput))
}
}
Ok(dict)
}
///|
/// Parses `input` as a Dictionary field value.
pub fn parse_dictionary(input : String) -> Result[SfDictionary, SfError] {
parse_dictionary_bytes(@utf8.encode(input, bom=false))
}
///|
/// Parses `input` as a Dictionary field value, in UTF-8 bytes.
pub fn parse_dictionary_bytes(input : Bytes) -> Result[SfDictionary, SfError] {
parse_field_bytes(input, ParseLimits::default(), parse_dictionary_cursor)
}
///|
/// Parses `input` as a Dictionary field value with custom limits.
pub fn parse_dictionary_with_limits(
input : String,
limits : ParseLimits,
) -> Result[SfDictionary, SfError] {
parse_field_bytes(
@utf8.encode(input, bom=false),
limits,
parse_dictionary_cursor,
)
}