pub struct Writer<'s, S: Sink> { /* private fields */ }Expand description
A canonical Structured Field writer (RFC 9651 section 4.1).
Calls must follow the structure: for an Item, one bare item and its parameters; for a List, members (bare items or inner lists), each with parameters; for a Dictionary, a key before each member. A dictionary member whose value is Boolean true is written as its key alone. Each call reserves its own room, so a call that fails writes nothing; the earlier calls’ output stays in the sink, and a caller that gets an error discards the field.
§Examples
use parse_net::{sfv::{BareItem, Writer}, SliceSink};
let mut buf = [0u8; 64];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::dictionary(&mut out);
w.key("u")?.integer(1)?;
w.key("i")?.boolean(true)?;
w.key("lang")?.open_inner_list()?.token("en")?.token("de")?.close_inner_list()?;
w.key("q")?.decimal(500)?.param("x", &BareItem::Token("a"))?;
w.finish()?;
assert_eq!(out.written(), b"u=1, i, lang=(en de), q=0.5;x=a");Implementations§
Source§impl<'s, S: Sink> Writer<'s, S>
impl<'s, S: Sink> Writer<'s, S>
Sourcepub fn item(out: &'s mut S) -> Self
pub fn item(out: &'s mut S) -> Self
A writer for an Item.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.integer(5)?.param_key("a")?.token("b")?;
w.finish()?;
assert_eq!(out.written(), b"5;a=b");Sourcepub fn list(out: &'s mut S) -> Self
pub fn list(out: &'s mut S) -> Self
A writer for a List.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.token("a")?.token("b")?;
w.finish()?;
assert_eq!(out.written(), b"a, b");Sourcepub fn dictionary(out: &'s mut S) -> Self
pub fn dictionary(out: &'s mut S) -> Self
A writer for a Dictionary.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::dictionary(&mut out);
w.key("a")?.integer(1)?;
w.key("b")?;
w.finish()?;
assert_eq!(out.written(), b"a=1, b");Sourcepub fn bare(&mut self, b: &BareItem<'_>) -> Result<&mut Self, WriteError>
pub fn bare(&mut self, b: &BareItem<'_>) -> Result<&mut Self, WriteError>
Writes a bare item.
§Errors
As the typed methods; WriteError::InvalidSequence out of order.
§Examples
use parse_net::{sfv::{BareItem, Writer}, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.bare(&BareItem::Token("x"))?.bare(&BareItem::Integer(-2))?;
w.finish()?;
assert_eq!(out.written(), b"x, -2");Sourcepub fn integer(&mut self, v: i64) -> Result<&mut Self, WriteError>
pub fn integer(&mut self, v: i64) -> Result<&mut Self, WriteError>
Writes an Integer.
§Errors
WriteError::OutOfRange beyond 15 digits; WriteError::Full;
WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.integer(-42)?;
assert!(w.integer(1_000_000_000_000_000).is_err());
w.finish()?;
assert_eq!(out.written(), b"-42");Sourcepub fn decimal(&mut self, thousandths: i64) -> Result<&mut Self, WriteError>
pub fn decimal(&mut self, thousandths: i64) -> Result<&mut Self, WriteError>
Writes a Decimal given in thousandths, with the shortest fractional
part (1.5, and 1.0 for a whole number).
§Errors
WriteError::OutOfRange beyond 12 integer digits;
WriteError::Full; WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.decimal(1500)?.decimal(2000)?.decimal(-125)?;
w.finish()?;
assert_eq!(out.written(), b"1.5, 2.0, -0.125");Sourcepub fn string(&mut self, s: &str) -> Result<&mut Self, WriteError>
pub fn string(&mut self, s: &str) -> Result<&mut Self, WriteError>
Writes a String, escaping only " and \.
§Errors
WriteError::Forbidden for a byte outside %x20-7E (use
display_string for other text);
WriteError::Full; WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.string("say \"hi\"")?;
w.finish()?;
assert_eq!(out.written(), br#""say \"hi\"""#);Sourcepub fn token(&mut self, t: &str) -> Result<&mut Self, WriteError>
pub fn token(&mut self, t: &str) -> Result<&mut Self, WriteError>
Writes a Token.
§Errors
WriteError::NotToken; WriteError::Full;
WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.token("gzip")?;
assert!(w.token("a b").is_err());
w.finish()?;
assert_eq!(out.written(), b"gzip");Sourcepub fn boolean(&mut self, b: bool) -> Result<&mut Self, WriteError>
pub fn boolean(&mut self, b: bool) -> Result<&mut Self, WriteError>
Writes a Boolean (?1 or ?0).
§Errors
WriteError::Full; WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.boolean(true)?.boolean(false)?;
w.finish()?;
assert_eq!(out.written(), b"?1, ?0");Sourcepub fn date(&mut self, secs: i64) -> Result<&mut Self, WriteError>
pub fn date(&mut self, secs: i64) -> Result<&mut Self, WriteError>
Writes a Date: @ and the seconds since the Unix epoch.
§Errors
WriteError::OutOfRange outside years 1 to 9999 (D-030);
WriteError::Full; WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.date(1_659_578_233)?;
w.finish()?;
assert_eq!(out.written(), b"@1659578233");Sourcepub fn display_string(&mut self, s: &str) -> Result<&mut Self, WriteError>
pub fn display_string(&mut self, s: &str) -> Result<&mut Self, WriteError>
Writes a Display String: %", the text with %, ", and every byte
outside %x20-7E as lowercase %xx, then ".
§Errors
WriteError::Full; WriteError::InvalidSequence.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.display_string("caf\u{e9}")?;
w.finish()?;
assert_eq!(out.written(), b"%\"caf%c3%a9\"");Sourcepub fn param(
&mut self,
key: &str,
v: &BareItem<'_>,
) -> Result<&mut Self, WriteError>
pub fn param( &mut self, key: &str, v: &BareItem<'_>, ) -> Result<&mut Self, WriteError>
Writes a parameter of the last item or inner list. A Boolean true value is written as the key alone.
§Errors
WriteError::NotToken for a key that is not
( lcalpha / "*" ) *( lcalpha / DIGIT / "_" / "-" / "." / "*" );
the value’s errors; WriteError::InvalidSequence before any item;
WriteError::Full.
§Examples
use parse_net::{sfv::{BareItem, Writer}, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.token("a")?.param("q", &BareItem::Integer(1))?.param("x", &BareItem::Boolean(true))?;
w.finish()?;
assert_eq!(out.written(), b"a;q=1;x");Sourcepub fn param_key(&mut self, key: &str) -> Result<&mut Self, WriteError>
pub fn param_key(&mut self, key: &str) -> Result<&mut Self, WriteError>
Writes the key of a parameter of the last item or inner list; the next
value call (string, integer, and
the others) writes its value, and a Boolean true writes nothing more.
For values that are not already a parsed BareItem.
§Errors
As param.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::item(&mut out);
w.token("text")?.param_key("lang")?.string("en \"GB\"")?.param_key("x")?.boolean(true)?;
w.finish()?;
assert_eq!(out.written(), br#"text;lang="en \"GB\"";x"#);Sourcepub fn key(&mut self, key: &str) -> Result<&mut Self, WriteError>
pub fn key(&mut self, key: &str) -> Result<&mut Self, WriteError>
Writes a dictionary key; its value follows (none means Boolean true).
§Errors
WriteError::NotToken for an invalid key;
WriteError::InvalidSequence outside a dictionary or inside an
inner list; WriteError::Full.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::dictionary(&mut out);
w.key("a")?;
w.key("b")?.integer(2)?;
w.finish()?;
assert_eq!(out.written(), b"a, b=2");Sourcepub fn open_inner_list(&mut self) -> Result<&mut Self, WriteError>
pub fn open_inner_list(&mut self) -> Result<&mut Self, WriteError>
Opens an inner list as the next list member or dictionary value.
§Errors
WriteError::InvalidSequence in an Item writer, inside an inner
list, or in a dictionary before a key; WriteError::Full.
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.open_inner_list()?.token("a")?.token("b")?.close_inner_list()?;
w.token("c")?;
w.finish()?;
assert_eq!(out.written(), b"(a b), c");Sourcepub fn close_inner_list(&mut self) -> Result<&mut Self, WriteError>
pub fn close_inner_list(&mut self) -> Result<&mut Self, WriteError>
Closes the open inner list; its parameters may follow.
§Errors
WriteError::InvalidSequence with no inner list open;
WriteError::Full.
§Examples
use parse_net::{sfv::{BareItem, Writer}, SliceSink};
let mut buf = [0u8; 32];
let mut out = SliceSink::new(&mut buf);
let mut w = Writer::list(&mut out);
w.open_inner_list()?.integer(1)?.close_inner_list()?.param("q", &BareItem::Integer(9))?;
w.finish()?;
assert_eq!(out.written(), b"(1);q=9");Sourcepub fn finish(self) -> Result<(), WriteError>
pub fn finish(self) -> Result<(), WriteError>
Ends the field.
§Errors
WriteError::InvalidSequence with an inner list open, a
parameter key without its value, or with nothing written (an empty List or Dictionary is not serialized at
all: omit the field, RFC 9651 section 4.1).
§Examples
use parse_net::{sfv::Writer, SliceSink};
let mut buf = [0u8; 8];
let mut out = SliceSink::new(&mut buf);
assert!(Writer::list(&mut out).finish().is_err());
let mut w = Writer::list(&mut out);
w.token("a")?;
w.finish()?;
assert_eq!(out.written(), b"a");