serde implementation of deb822 format
Deb822 format is used by Debian and derivatives distros in package (source and
binary), repositories and sources.list/*.sources.
We would implement all thing needed to parse theses files.
API
# use BTreeMap;
# use Cursor;
let stanza = "A: B";
let file = "A: B\n\nC: D\n\n";
let expect_stanza = from;
let expect_stanza_buf = from;
let expect_file = vec!;
let expect_file_buf = vec!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
let mut output = vec!;
to_writer.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
let mut output = vec!;
to_writer.unwrap;
assert_eq!;
The format
Deb822 format is documentation can be found in deb822(5).
Comment
Line start by # is a comment-line and can be present anywhere in file,
including in the middle of a multiline value.
Field name
Field name must be only contains ASCII char, excluding control characters, space
and : and not begins with # or -.
Field name and value are separated by a :.
[!NOTE] Some invalid key can be parsed in some case. Restriction applied is not start with space
or#and not contains any dash#or newline\n
[!INFO] Deb822 documentation tell field name are case insensitive, this isn't implemented, we need to use as key a str-insensitive type
# use BTreeMap;
let s = "-Invalid: Value1
Invali\rd: Value2
Invalid key: Value3
Invalidéééé: Value4
Ke#1: Value5
Valid-Key: Value6";
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Value
Simple
Simple value are a all following colon (:) until the end of the line.
One space after colon are trimmed.
# use BTreeMap;
let s = r#"Key1: Value1
Key2:Value2
Key3: Value3
Key4: Value4 "#;
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
let equivalent_fmt = r#"Key1: Value1
Key2: Value2
Key3: Value3
Key4: Value4 "#;
assert_eq!;
Folded
A folded value is simply a value continued to next line.
Continuation line are prefixed by a space .
Deserialize into a String just work, but for borrow-deserialize
(e.g. into &str) isn't possible with multi-line value (a space removed at
begin of each line).
Borrow-deserialize each line separated is possible (e.g. into Vec<&str>).
# use BTreeMap;
let s = r#"Key1: Value1
On multiple line
Key2: Value2
On multiple line
.
With empty line in middle
"#;
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
dbg!;
println!;
println!;
assert_eq!;
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
Multiline
A multiline value has same syntax as folded value, but newline are signifiant. It is equals to folded value (this implementation keep always newline).
In some file first line (after colon) are different means as continuations lines. For that you can deserialize it into a pair.
# use BTreeMap;
# // NOTE: comment in markdown must start with double '#' because first is
# // removed by cargo doc for hide line
let s = r#"
Key1: Value1
On multiple line
Key2: Value2
On multiple line
## Comment are allowed inside mutli-line value
.
With empty line in middle
"#;
let comment_trimmed = r#"Key1: Value1
On multiple line
Key2: Value2
On multiple line
.
With empty line in middle
"#;
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
let map: = from_str.unwrap;
assert_eq!;
assert_eq!;
assert_eq!;
bool on deb822
trueare serialize to"yes"falseare serialize to"no"
For now only yes and no value are recognized as boolean, but in future some
other string can be added to list.
integer and float on deb822
Both are deserilized by using FromStr trait and serialized with Display trait.
Stanza
Stanza is just a list of key-value line.
Document
A document is one or more stanzas of fields. Stanzas are separated by empty line (really empty or only contains space and tab).
# use HashMap;
let s = r#"
Stanza1: Value1
Stanza2: Value2
Stanza3: Value2
"#;
let expected = r#"Stanza1: Value1
Stanza2: Value2
Stanza3: Value2
"#;
let list: = from_str.unwrap;
assert_eq!;
assert_eq!;
# use HashMap;
let s = r#"
Stanza1: Value1
## a Comment
## a Comment
## a Comment
Stanza2: Value2
"#;
let expected = r#"Stanza1: Value1
Stanza2: Value2
"#;
let list: = from_str.unwrap;
assert_eq!;
assert_eq!;
The first stanza of a document can be have special means, you can deserialize the document to a pair for extract it automatically.
# use HashMap;
let s = r#"Stanza1: Value1
Stanza2: Value2
Stanza3: Value3
"#;
type Stanza<'a> = ;
let list: = from_str.unwrap;
assert_eq!;
assert_eq!;
Use with custom struct
Implement serializer and deserializer for serde.
# use ;
// In deb822, we not have standard, some field named on PascalCase and other
// with title-capitalized kebab-case (not supported by serde)
let s = r#"
Borrow-Str: string one
#Comment are removed
#first space after colon (:) are removed if present
String: string two
Flag: yes
Size: 25677
Description: title line
continuation line
on two line
DescriptionAlt: title line
continuation line
on two line
DescriptionAlt2: title line
continuation line
on two line
"#;
let _: Info = from_str.unwrap;