// sf_model.mbt — Structured Field data model (RFC 9651 subset).
//
// moon-httpsig does not implement a full RFC 9651 library. It implements the
// subset needed by RFC 9421: Dictionary, Inner List, String, Token, Integer,
// Byte Sequence, Boolean, and Parameters. Order is preserved everywhere
// (dictionary order, inner-list order, parameter order) because RFC 9421
// signatures depend on canonical serialization.
///|
/// The "bare item" of a structured field item: the value without parameters.
pub(all) enum SfBareItem {
/// An RFC 9651 string, `"..."`.
SfString(String)
/// An RFC 9651 token, `token`.
SfToken(String)
/// An RFC 9651 integer, `-?digits` (fits in 64-bit signed).
SfInteger(Int64)
/// An RFC 9651 byte sequence, `:base64:`.
SfByteSequence(Bytes)
/// An RFC 9651 boolean, `?0` / `?1`.
SfBoolean(Bool)
}
///|
/// A single structured field parameter: `name=value`.
pub(all) struct SfParameter {
name : String
value : SfBareItem
}
///|
/// A structured field item: bare item plus its parameters.
pub(all) struct SfItem {
value : SfBareItem
parameters : Array[SfParameter]
}
///|
/// A structured field inner list: `(items) params`.
pub(all) struct SfInnerList {
items : Array[SfItem]
parameters : Array[SfParameter]
}
///|
/// A dictionary member: either an item or an inner list.
pub(all) enum SfMember {
ItemMember(SfItem)
InnerListMember(SfInnerList)
}
///|
/// A single dictionary entry: a key plus its member value.
pub(all) struct SfDictionaryEntry {
key : String
value : SfMember
}
///|
/// Constructs a parameter with the given name and value.
pub fn sf_param(name : String, value : SfBareItem) -> SfParameter {
{ name, value }
}
///|
/// Constructs a bare string item.
pub fn sf_string(v : String) -> SfItem {
{ value: SfString(v), parameters: Array::new() }
}
///|
/// Constructs a bare token item.
pub fn sf_token(v : String) -> SfItem {
{ value: SfToken(v), parameters: Array::new() }
}
///|
/// Constructs a bare integer item.
pub fn sf_integer(v : Int64) -> SfItem {
{ value: SfInteger(v), parameters: Array::new() }
}
///|
/// Constructs a bare boolean item.
pub fn sf_boolean(v : Bool) -> SfItem {
{ value: SfBoolean(v), parameters: Array::new() }
}
///|
/// Constructs a bare byte-sequence item.
pub fn sf_bytes(v : Bytes) -> SfItem {
{ value: SfByteSequence(v), parameters: Array::new() }
}
///|
/// Returns the parameter with the given name (exact case-sensitive match),
/// or `None`.
pub fn SfItem::parameter(self : SfItem, name : String) -> SfParameter? {
for p in self.parameters {
if p.name == name {
return Some(p)
}
}
None
}