RFC 9651 Structured Field Values parser and serializer for MoonBit
| Feature | Parse | Serialize | Notes |
|---|---|---|---|
| Item | ✅ | ✅ | Top-level parameterized values |
| List | ✅ | ✅ | Top-level comma-separated arrays |
| Dictionary | ✅ | ✅ | Top-level comma-separated key-value maps |
| Inner List | ✅ | ✅ | Parenthesized item sequences (item1 item2) |
| Parameters | ✅ | ✅ | Ordered semicolon key-value pairs ;k=v |
| Integer | ✅ | ✅ | 64-bit integers in range ±999,999,999,999,999 |
| Decimal | ✅ | ✅ | 12 integer digits, 1–3 fractional digits, canonical round-half-even |
| String | ✅ | ✅ | ASCII strings with strict \" and \\ escaping |
| Token | ✅ | ✅ | Valid RFC identifiers and MIME/symbol tokens |
| Byte Sequence | ✅ | ✅ | Base64-encoded binary content :...: |
| Boolean | ✅ | ✅ | ?1 (true), ?0 (false), and parameter shorthand |
| Date | ✅ | ✅ | Unix timestamps with @... prefix |
| Display String | ✅ | ✅ | UTF-8 percent-encoded display strings %"..." |
moon add Sam-Hui-dot/moon-sfvimport {
"Sam-Hui-dot/moon-sfv" @sfv,
}let input = "example;secure;level=2"
match @sfv.parse_item(input) {
Ok(item) => {
// item.value is BareItem::SfToken("example")
// item.parameters has { "secure": true, "level": 2 }
match @sfv.serialize_item(item) {
Ok(canonical) => println(canonical) // "example;secure;level=2"
Err(_) => println("Serialization failed")
}
}
Err(_) => println("Parsing failed")
}let input = "text/html;q=1.0, (\"gzip\" \"br\");level=9"
match @sfv.parse_list(input) {
Ok(list) => {
// list contains Item and InnerList members
match @sfv.serialize_list(list) {
Ok(canonical) => println(canonical)
Err(_) => println("Serialization failed")
}
}
Err(_) => println("Parsing failed")
}let input = "en=\"Applepie\", da=:w4ZibGV0w6ZydGUK:, active, flags=(x y)"
match @sfv.parse_dictionary(input) {
Ok(dict) => {
// dict contains ordered key-value pairs with boolean shorthand support
match @sfv.serialize_dictionary(dict) {
Ok(canonical) => println(canonical)
Err(_) => println("Serialization failed")
}
}
Err(_) => println("Parsing failed")
}pub(all) enum BareItem {
SfInteger(Int64)
SfDecimal(Double)
SfString(String)
SfToken(String)
SfByteSequence(Bytes)
SfBoolean(Bool)
SfDate(Int64)
SfDisplayString(String)
} derive(Eq, Debug)
pub(all) struct Parameter {
key : String
value : BareItem
} derive(Eq, Debug)
pub(all) struct Item {
value : BareItem
parameters : Array[Parameter]
} derive(Eq, Debug)
pub(all) struct InnerList {
items : Array[Item]
parameters : Array[Parameter]
} derive(Eq, Debug)
pub(all) enum ListMember {
Item(Item)
InnerList(InnerList)
} derive(Eq, Debug)
pub(all) struct DictionaryMember {
key : String
value : ListMember
} derive(Eq, Debug)pub fn parse_item(String) -> Result[Item, ParseError]
pub fn serialize_item(Item) -> Result[String, SerializeError]
pub fn parse_list(String) -> Result[Array[ListMember], ParseError]
pub fn serialize_list(Array[ListMember]) -> Result[String, SerializeError]
pub fn parse_dictionary(String) -> Result[Array[DictionaryMember], ParseError]
pub fn serialize_dictionary(Array[DictionaryMember]) -> Result[String, SerializeError]
pub fn base64_encode(Bytes) -> String
pub fn base64_decode(String) -> Bytes?
pub fn string_to_utf8_bytes(String) -> Array[Byte]
pub fn utf8_bytes_to_string(Array[Byte]) -> String?moon check --deny-warn
moon test
moon fmt --checkmoon run examples/mainpub(all) enum ParseError {
EmptyInput
InvalidBoolean(Int)
InvalidInteger(String)
IntegerOutOfRange(String)
InvalidDecimal(String)
DecimalOutOfRange(String)
UnterminatedString(Int)
InvalidStringEscape(Int)
InvalidStringCharacter(Int)
InvalidToken(Int)
InvalidByteSequence(Int)
InvalidDate(String)
InvalidDisplayString(Int)
InvalidParameterKey(Int)
InvalidDictionaryKey(Int)
InvalidInnerList(Int)
InvalidList(Int)
InvalidDictionary(Int)
UnsupportedBareItem(Int)
TrailingCharacters(Int)
} derive(Eq, Debug)pub(all) enum SerializeError {
IntegerOutOfRange(Int64)
DecimalOutOfRange(Double)
InvalidDecimal(Double)
DateOutOfRange(Int64)
InvalidString(String)
InvalidToken(String)
InvalidByteSequence
InvalidDisplayString(String)
InvalidParameterKey(String)
InvalidDictionaryKey(String)
UnsupportedBareItem
} derive(Eq, Debug)Install
Download zipRFC 9651 Structured Field Values parser and serializer for MoonBit