Skip to main content

parse_net/sfv/
mod.rs

1//! Structured Field Values (RFC 9651): Items, Lists, and Dictionaries with
2//! every bare item type, parsed into borrowed views.
3//!
4//! The parser follows RFC 9651 section 4.2 exactly, as a loop with explicit
5//! state; inner lists cannot nest, so there is no recursion. A field is
6//! accepted or refused as a whole, as section 4.2 requires. Every limit of
7//! section 3 is enforced through [`Limits`], whose defaults meet each
8//! minimum.
9//!
10//! # Examples
11//!
12//! ```
13//! use parse_net::sfv::{self, BareItem, Member};
14//!
15//! let site = sfv::parse_item(b"same-origin")?;
16//! assert_eq!(site.bare, BareItem::Token("same-origin"));
17//!
18//! let prio = sfv::parse_dictionary(b"u=1, i")?;
19//! assert!(matches!(prio.get("u"), Some(Member::Item(i)) if i.bare == BareItem::Integer(1)));
20//! assert!(matches!(prio.get("i"), Some(Member::Item(i)) if i.bare == BareItem::Boolean(true)));
21//!
22//! let list = sfv::parse_list(b"(\"foo\" \"bar\");lvl=5, abc;a=?0")?;
23//! assert_eq!(list.len(), 2);
24//! let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
25//! assert_eq!(inner.len(), 2);
26//! # Ok::<(), parse_net::ParseError>(())
27//! ```
28
29#[cfg(feature = "alloc")]
30#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
31pub mod owned;
32mod parse;
33mod write;
34
35pub use write::Writer;
36
37use parse::{Cursor, Events, Nothing};
38
39use crate::{
40    error::{ErrorKind, ParseError, Result, err},
41    limits::Limits,
42};
43
44/// Limits for walking text that was already validated: every bound at its
45/// maximum, so a view never refuses what its parse accepted.
46const RELAXED: Limits = Limits::DEFAULT
47    .max_list_members(u16::MAX)
48    .max_inner_list_members(u16::MAX)
49    .max_params(u16::MAX)
50    .max_dictionary_members(u16::MAX)
51    .max_key_len(u16::MAX)
52    .max_string_len(u16::MAX)
53    .max_token_len(u16::MAX)
54    .max_byte_seq_len(u32::MAX);
55
56/// A bare item (RFC 9651 section 3.3).
57///
58/// # Examples
59///
60/// ```
61/// use parse_net::sfv::{self, BareItem};
62///
63/// assert_eq!(sfv::parse_item(b"42")?.bare, BareItem::Integer(42));
64/// assert_eq!(sfv::parse_item(b"abc")?.bare, BareItem::Token("abc"));
65/// assert!(matches!(sfv::parse_item(b"\"hi\"")?.bare, BareItem::String(s) if s.eq_str("hi")));
66/// # Ok::<(), parse_net::ParseError>(())
67/// ```
68#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
69pub enum BareItem<'a> {
70    /// An Integer, at most 15 digits.
71    Integer(i64),
72    /// A Decimal, in thousandths.
73    Decimal(Decimal),
74    /// A String.
75    String(SfString<'a>),
76    /// A Token (ASCII by construction).
77    Token(&'a str),
78    /// A Byte Sequence, still base64.
79    ByteSeq(ByteSeq<'a>),
80    /// A Boolean.
81    Boolean(bool),
82    /// A Date: seconds since the Unix epoch, within years 1 to 9999.
83    Date(i64),
84    /// A Display String, still percent-encoded.
85    DisplayString(DisplayString<'a>),
86}
87
88/// A Decimal in thousandths: at most 12 integer and 3 fractional digits.
89///
90/// # Examples
91///
92/// ```
93/// use parse_net::sfv::{self, BareItem, Decimal};
94///
95/// assert_eq!(sfv::parse_item(b"-1.5")?.bare, BareItem::Decimal(Decimal::from_thousandths(-1500)?));
96/// assert!(Decimal::from_thousandths(1_000_000_000_000_000).is_err());
97/// # Ok::<(), parse_net::ParseError>(())
98/// ```
99#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
100pub struct Decimal(pub(crate) i64);
101
102impl Decimal {
103    /// The decimal `t / 1000`.
104    ///
105    /// # Errors
106    ///
107    /// [`ErrorKind::OutOfRange`] beyond 12 integer digits.
108    ///
109    /// # Examples
110    ///
111    /// ```
112    /// use parse_net::sfv::Decimal;
113    ///
114    /// assert_eq!(Decimal::from_thousandths(1500)?.thousandths(), 1500);
115    /// assert!(Decimal::from_thousandths(1_000_000_000_000_000).is_err());
116    /// # Ok::<(), parse_net::ParseError>(())
117    /// ```
118    pub const fn from_thousandths(t: i64) -> Result<Self> {
119        if t > parse::INTEGER_MAX || t < -parse::INTEGER_MAX {
120            return err(ErrorKind::OutOfRange, 0);
121        }
122        Ok(Self(t))
123    }
124
125    /// The value in thousandths.
126    ///
127    /// # Examples
128    ///
129    /// ```
130    /// use parse_net::sfv::{self, BareItem};
131    ///
132    /// let BareItem::Decimal(d) = sfv::parse_item(b"2.25")?.bare else { unreachable!() };
133    /// assert_eq!(d.thousandths(), 2250);
134    /// # Ok::<(), parse_net::ParseError>(())
135    /// ```
136    #[must_use]
137    pub const fn thousandths(self) -> i64 {
138        self.0
139    }
140}
141
142/// A String: the content between the quotes, only `\"` and `\\` escapes.
143///
144/// # Examples
145///
146/// ```
147/// use parse_net::sfv::{self, BareItem};
148///
149/// let BareItem::String(s) = sfv::parse_item(b"\"hello\"")?.bare else { unreachable!() };
150/// assert!(s.eq_str("hello"));
151/// # Ok::<(), parse_net::ParseError>(())
152/// ```
153#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
154pub struct SfString<'a> {
155    raw: &'a str,
156    escapes: bool,
157}
158
159impl<'a> SfString<'a> {
160    /// The content as sent, escapes included (ASCII by construction).
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use parse_net::sfv::{self, BareItem};
166    ///
167    /// let BareItem::String(s) = sfv::parse_item(br#""a\"b""#)?.bare else { unreachable!() };
168    /// assert_eq!(s.raw(), r#"a\"b"#);
169    /// # Ok::<(), parse_net::ParseError>(())
170    /// ```
171    #[must_use]
172    pub const fn raw(&self) -> &'a str {
173        self.raw
174    }
175
176    /// The value with no copy, when it has no escape.
177    ///
178    /// # Examples
179    ///
180    /// ```
181    /// use parse_net::sfv::{self, BareItem};
182    ///
183    /// let BareItem::String(s) = sfv::parse_item(b"\"plain\"")?.bare else { unreachable!() };
184    /// assert_eq!(s.as_plain(), Some("plain"));
185    /// let BareItem::String(e) = sfv::parse_item(br#""a\"b""#)?.bare else { unreachable!() };
186    /// assert_eq!(e.as_plain(), None);
187    /// # Ok::<(), parse_net::ParseError>(())
188    /// ```
189    #[must_use]
190    pub const fn as_plain(&self) -> Option<&'a str> {
191        if self.escapes { None } else { Some(self.raw) }
192    }
193
194    fn bytes(&self) -> crate::text::Unescape<'a> {
195        crate::text::Quoted::from_raw(self.raw.as_bytes(), self.escapes).bytes()
196    }
197
198    /// The length of the unescaped value.
199    ///
200    /// # Examples
201    ///
202    /// ```
203    /// use parse_net::sfv::{self, BareItem};
204    ///
205    /// let BareItem::String(s) = sfv::parse_item(br#""a\"b""#)?.bare else { unreachable!() };
206    /// assert_eq!(s.raw().len(), 4);
207    /// assert_eq!(s.unescaped_len(), 3);
208    /// # Ok::<(), parse_net::ParseError>(())
209    /// ```
210    #[must_use]
211    pub fn unescaped_len(&self) -> usize {
212        if self.escapes {
213            self.bytes().count()
214        } else {
215            self.raw.len()
216        }
217    }
218
219    /// Writes the unescaped value into `out` and returns it.
220    ///
221    /// # Errors
222    ///
223    /// [`ErrorKind::BufferTooSmall`]; nothing is written.
224    ///
225    /// # Examples
226    ///
227    /// ```
228    /// use parse_net::sfv::{self, BareItem};
229    ///
230    /// let BareItem::String(s) = sfv::parse_item(b"\"a \\\"b\\\"\"")?.bare else { unreachable!() };
231    /// let mut buf = [0u8; 8];
232    /// assert_eq!(s.unescape_into(&mut buf)?, "a \"b\"");
233    /// assert!(s.eq_str("a \"b\""));
234    /// # Ok::<(), parse_net::ParseError>(())
235    /// ```
236    pub fn unescape_into<'b>(&self, out: &'b mut [u8]) -> Result<&'b str> {
237        let len = self.unescaped_len();
238        let Some(dst) = out.get_mut(..len) else {
239            return err(ErrorKind::BufferTooSmall, 0);
240        };
241        for (d, b) in dst.iter_mut().zip(self.bytes()) {
242            *d = b;
243        }
244        // ASCII in, ASCII out.
245        core::str::from_utf8(dst).map_err(|_| ParseError::new(ErrorKind::InvalidUtf8, 0))
246    }
247
248    /// Whether the unescaped value equals `other`, with no buffer.
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// use parse_net::sfv::{self, BareItem};
254    ///
255    /// let BareItem::String(s) = sfv::parse_item(br#""a\"b""#)?.bare else { unreachable!() };
256    /// assert!(s.eq_str("a\"b"));
257    /// assert!(!s.eq_str(r#"a\"b"#));
258    /// # Ok::<(), parse_net::ParseError>(())
259    /// ```
260    #[must_use]
261    pub fn eq_str(&self, other: &str) -> bool {
262        self.bytes().eq(other.bytes())
263    }
264}
265
266/// A Byte Sequence: the base64 text between the colons.
267///
268/// # Examples
269///
270/// ```
271/// use parse_net::sfv::{self, BareItem};
272///
273/// let BareItem::ByteSeq(b) = sfv::parse_item(b":aGVsbG8=:")?.bare else { unreachable!() };
274/// assert_eq!(b.decoded_len(), 5);
275/// # Ok::<(), parse_net::ParseError>(())
276/// ```
277#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
278pub struct ByteSeq<'a> {
279    raw: &'a [u8],
280}
281
282impl<'a> ByteSeq<'a> {
283    /// The base64 text, padding included if it was sent.
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// use parse_net::sfv::{self, BareItem};
289    ///
290    /// let BareItem::ByteSeq(b) = sfv::parse_item(b":aGVsbG8=:")?.bare else { unreachable!() };
291    /// assert_eq!(b.raw(), b"aGVsbG8=");
292    /// # Ok::<(), parse_net::ParseError>(())
293    /// ```
294    #[must_use]
295    pub const fn raw(&self) -> &'a [u8] {
296        self.raw
297    }
298
299    /// The exact length of the decoded bytes.
300    ///
301    /// # Examples
302    ///
303    /// ```
304    /// use parse_net::sfv::{self, BareItem};
305    ///
306    /// let BareItem::ByteSeq(b) = sfv::parse_item(b":cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==:")?.bare else { unreachable!() };
307    /// assert_eq!(b.decoded_len(), 31);
308    /// # Ok::<(), parse_net::ParseError>(())
309    /// ```
310    #[must_use]
311    pub fn decoded_len(&self) -> usize {
312        let body = self.raw.iter().take_while(|&&b| b != b'=').count();
313        body / 4 * 3 + (body % 4).saturating_sub(1)
314    }
315}
316
317/// A Display String: the percent-encoded text between the quotes, validated
318/// as UTF-8 during the parse.
319///
320/// # Examples
321///
322/// ```
323/// use parse_net::sfv::{self, BareItem};
324///
325/// let BareItem::DisplayString(d) = sfv::parse_item(b"%\"caf%c3%a9\"")?.bare else { unreachable!() };
326/// assert_eq!(d.raw(), b"caf%c3%a9");
327/// assert_eq!(d.decoded_len(), 5);
328/// # Ok::<(), parse_net::ParseError>(())
329/// ```
330#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
331pub struct DisplayString<'a> {
332    raw: &'a [u8],
333}
334
335impl<'a> DisplayString<'a> {
336    /// The text as sent, `%xx` triples included.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// use parse_net::sfv::{self, BareItem};
342    ///
343    /// let BareItem::DisplayString(d) = sfv::parse_item(b"%\"50%25\"")?.bare else { unreachable!() };
344    /// assert_eq!(d.raw(), b"50%25");
345    /// # Ok::<(), parse_net::ParseError>(())
346    /// ```
347    #[must_use]
348    pub const fn raw(&self) -> &'a [u8] {
349        self.raw
350    }
351
352    /// The length of the decoded UTF-8 text.
353    ///
354    /// # Examples
355    ///
356    /// ```
357    /// use parse_net::sfv::{self, BareItem};
358    ///
359    /// let BareItem::DisplayString(d) = sfv::parse_item(b"%\"caf%c3%a9\"")?.bare else { unreachable!() };
360    /// assert_eq!(d.decoded_len(), 5);
361    /// # Ok::<(), parse_net::ParseError>(())
362    /// ```
363    #[must_use]
364    pub fn decoded_len(&self) -> usize {
365        crate::pct::decoded_len(self.raw).unwrap_or(0)
366    }
367
368    /// Writes the decoded text into `out` and returns it.
369    ///
370    /// # Errors
371    ///
372    /// [`ErrorKind::BufferTooSmall`]; nothing is written.
373    ///
374    /// # Examples
375    ///
376    /// ```
377    /// use parse_net::sfv::{self, BareItem};
378    ///
379    /// let BareItem::DisplayString(d) = sfv::parse_item(b"%\"caf%c3%a9\"")?.bare else { unreachable!() };
380    /// let mut buf = [0u8; 8];
381    /// assert_eq!(d.decode_into(&mut buf)?, "caf\u{e9}");
382    /// # Ok::<(), parse_net::ParseError>(())
383    /// ```
384    pub fn decode_into<'b>(&self, out: &'b mut [u8]) -> Result<&'b str> {
385        crate::pct::decode_utf8_into(self.raw, out)
386    }
387}
388
389/// Parameters of an item or an inner list. A repeated key keeps every
390/// occurrence; [`get`](Self::get) takes the last, as RFC 9651 requires.
391///
392/// # Examples
393///
394/// ```
395/// use parse_net::sfv::{self, BareItem};
396///
397/// let params = sfv::parse_item(b"abc;a=1;b")?.params;
398/// assert_eq!(params.len(), 2);
399/// assert_eq!(params.get("a"), Some(BareItem::Integer(1)));
400/// assert_eq!(params.get("b"), Some(BareItem::Boolean(true)));
401/// # Ok::<(), parse_net::ParseError>(())
402/// ```
403#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
404pub struct SfParams<'a> {
405    text: &'a [u8],
406    count: usize,
407}
408
409impl<'a> SfParams<'a> {
410    const EMPTY: Self = Self {
411        text: &[],
412        count: 0,
413    };
414
415    /// The parameters, in order.
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// use parse_net::sfv::{self, BareItem};
421    ///
422    /// let params = sfv::parse_item(b"abc;a=1;b")?.params;
423    /// let mut it = params.iter();
424    /// assert_eq!(it.next(), Some(("a", BareItem::Integer(1))));
425    /// assert_eq!(it.next(), Some(("b", BareItem::Boolean(true))));
426    /// assert_eq!(it.next(), None);
427    /// # Ok::<(), parse_net::ParseError>(())
428    /// ```
429    #[must_use]
430    pub fn iter(&self) -> ParamIter<'a> {
431        ParamIter {
432            c: Cursor::new(self.text),
433        }
434    }
435
436    /// The value of `key`: the last occurrence.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use parse_net::sfv::{self, BareItem};
442    ///
443    /// let params = sfv::parse_item(b"x;a=1;a=2")?.params;
444    /// assert_eq!(params.get("a"), Some(BareItem::Integer(2)));
445    /// assert_eq!(params.get("z"), None);
446    /// # Ok::<(), parse_net::ParseError>(())
447    /// ```
448    #[must_use]
449    pub fn get(&self, key: &str) -> Option<BareItem<'a>> {
450        self.iter()
451            .filter(|(k, _)| *k == key)
452            .last()
453            .map(|(_, v)| v)
454    }
455
456    /// The number of parameters, repeats included.
457    ///
458    /// # Examples
459    ///
460    /// ```
461    /// let params = parse_net::sfv::parse_item(b"x;a=1;a=2")?.params;
462    /// assert_eq!(params.len(), 2);
463    /// # Ok::<(), parse_net::ParseError>(())
464    /// ```
465    #[must_use]
466    pub const fn len(&self) -> usize {
467        self.count
468    }
469
470    /// Whether there are no parameters.
471    ///
472    /// # Examples
473    ///
474    /// ```
475    /// use parse_net::sfv;
476    ///
477    /// assert!(sfv::parse_item(b"x")?.params.is_empty());
478    /// assert!(!sfv::parse_item(b"x;a")?.params.is_empty());
479    /// # Ok::<(), parse_net::ParseError>(())
480    /// ```
481    #[must_use]
482    pub const fn is_empty(&self) -> bool {
483        self.count == 0
484    }
485}
486
487/// The parameters of a validated [`SfParams`].
488///
489/// # Examples
490///
491/// ```
492/// use parse_net::sfv::{self, BareItem};
493///
494/// let params = sfv::parse_item(b"x;q=0.5")?.params;
495/// let mut it = params.iter();
496/// assert!(matches!(it.next(), Some(("q", BareItem::Decimal(d))) if d.thousandths() == 500));
497/// assert!(it.next().is_none());
498/// # Ok::<(), parse_net::ParseError>(())
499/// ```
500#[derive(Clone, Debug)]
501pub struct ParamIter<'a> {
502    c: Cursor<'a>,
503}
504
505impl<'a> Iterator for ParamIter<'a> {
506    type Item = (&'a str, BareItem<'a>);
507
508    fn next(&mut self) -> Option<Self::Item> {
509        if self.c.peek() != Some(b';') {
510            return None;
511        }
512        self.c.bump();
513        self.c.skip_sp();
514        let k = parse::key(&mut self.c, &RELAXED).ok()?;
515        let v = if self.c.peek() == Some(b'=') {
516            self.c.bump();
517            parse::bare_item(&mut self.c, &RELAXED).ok()?
518        } else {
519            BareItem::Boolean(true)
520        };
521        Some((k, v))
522    }
523}
524
525/// An item: a bare item and its parameters.
526///
527/// # Examples
528///
529/// ```
530/// use parse_net::sfv::{self, BareItem};
531///
532/// let item = sfv::parse_item(b"abc;v=2")?;
533/// assert_eq!(item.bare, BareItem::Token("abc"));
534/// assert_eq!(item.params.get("v"), Some(BareItem::Integer(2)));
535/// # Ok::<(), parse_net::ParseError>(())
536/// ```
537#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
538pub struct Item<'a> {
539    /// The bare item.
540    pub bare: BareItem<'a>,
541    /// Its parameters.
542    pub params: SfParams<'a>,
543}
544
545/// An inner list: items in parentheses, and its own parameters.
546///
547/// # Examples
548///
549/// ```
550/// use parse_net::sfv::{self, BareItem, Member};
551///
552/// let list = sfv::parse_list(b"(a b);q=1")?;
553/// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
554/// assert_eq!(inner.len(), 2);
555/// assert_eq!(inner.params().get("q"), Some(BareItem::Integer(1)));
556/// # Ok::<(), parse_net::ParseError>(())
557/// ```
558#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
559pub struct InnerList<'a> {
560    text: &'a [u8],
561    count: usize,
562    params: SfParams<'a>,
563}
564
565impl<'a> InnerList<'a> {
566    /// The items, in order.
567    ///
568    /// # Examples
569    ///
570    /// ```
571    /// use parse_net::sfv::{self, BareItem, Member};
572    ///
573    /// let list = sfv::parse_list(b"(a b)")?;
574    /// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
575    /// assert!(inner.iter().map(|i| i.bare).eq([BareItem::Token("a"), BareItem::Token("b")]));
576    /// # Ok::<(), parse_net::ParseError>(())
577    /// ```
578    #[must_use]
579    pub fn iter(&self) -> InnerIter<'a> {
580        let mut c = Cursor::new(self.text);
581        c.bump(); // "("
582        InnerIter { c }
583    }
584
585    /// The number of items.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use parse_net::sfv::{self, Member};
591    ///
592    /// let list = sfv::parse_list(b"(1 2 3)")?;
593    /// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
594    /// assert_eq!(inner.len(), 3);
595    /// # Ok::<(), parse_net::ParseError>(())
596    /// ```
597    #[must_use]
598    pub const fn len(&self) -> usize {
599        self.count
600    }
601
602    /// Whether the inner list is empty (`()`).
603    ///
604    /// # Examples
605    ///
606    /// ```
607    /// use parse_net::sfv::{self, Member};
608    ///
609    /// let list = sfv::parse_list(b"()")?;
610    /// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
611    /// assert!(inner.is_empty());
612    /// # Ok::<(), parse_net::ParseError>(())
613    /// ```
614    #[must_use]
615    pub const fn is_empty(&self) -> bool {
616        self.count == 0
617    }
618
619    /// The inner list's own parameters.
620    ///
621    /// # Examples
622    ///
623    /// ```
624    /// use parse_net::sfv::{self, BareItem, Member};
625    ///
626    /// let list = sfv::parse_list(b"(a);lvl=5")?;
627    /// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
628    /// assert_eq!(inner.params().get("lvl"), Some(BareItem::Integer(5)));
629    /// # Ok::<(), parse_net::ParseError>(())
630    /// ```
631    #[must_use]
632    pub const fn params(&self) -> SfParams<'a> {
633        self.params
634    }
635}
636
637/// The items of a validated [`InnerList`].
638///
639/// # Examples
640///
641/// ```
642/// use parse_net::sfv::{self, BareItem, Member};
643///
644/// let list = sfv::parse_list(b"(a;x b)")?;
645/// let Some(Member::InnerList(inner)) = list.iter().next() else { unreachable!() };
646/// let mut items = inner.iter();
647/// assert_eq!(items.next().map(|i| i.params.len()), Some(1));
648/// assert_eq!(items.next().map(|i| i.bare), Some(BareItem::Token("b")));
649/// assert!(items.next().is_none());
650/// # Ok::<(), parse_net::ParseError>(())
651/// ```
652#[derive(Clone, Debug)]
653pub struct InnerIter<'a> {
654    c: Cursor<'a>,
655}
656
657impl<'a> Iterator for InnerIter<'a> {
658    type Item = Item<'a>;
659
660    fn next(&mut self) -> Option<Item<'a>> {
661        self.c.skip_sp();
662        if matches!(self.c.peek(), Some(b')') | None) {
663            return None;
664        }
665        item_view(&mut self.c)
666    }
667}
668
669/// A list or dictionary member.
670///
671/// # Examples
672///
673/// ```
674/// use parse_net::sfv::{self, BareItem, Member};
675///
676/// let list = sfv::parse_list(b"a, (b c)")?;
677/// let mut it = list.iter();
678/// assert!(matches!(it.next(), Some(Member::Item(i)) if i.bare == BareItem::Token("a")));
679/// assert!(matches!(it.next(), Some(Member::InnerList(l)) if l.len() == 2));
680/// # Ok::<(), parse_net::ParseError>(())
681/// ```
682#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
683pub enum Member<'a> {
684    /// An item.
685    Item(Item<'a>),
686    /// An inner list.
687    InnerList(InnerList<'a>),
688}
689
690/// Parses an item at the cursor of validated text.
691fn item_view<'a>(c: &mut Cursor<'a>) -> Option<Item<'a>> {
692    let bare = parse::bare_item(c, &RELAXED).ok()?;
693    let params = params_view(c)?;
694    Some(Item { bare, params })
695}
696
697fn params_view<'a>(c: &mut Cursor<'a>) -> Option<SfParams<'a>> {
698    let start = c.i;
699    let count = parse::params(c, &RELAXED, |_, _| Ok(())).ok()?;
700    Some(SfParams {
701        text: c.s.get(start..c.i).unwrap_or(&[]),
702        count,
703    })
704}
705
706/// Parses a member at the cursor of validated text.
707fn member_view<'a>(c: &mut Cursor<'a>) -> Option<Member<'a>> {
708    if c.peek() != Some(b'(') {
709        return item_view(c).map(Member::Item);
710    }
711    let start = c.i;
712    let mut inner = *c;
713    inner.bump(); // "("
714    let mut count = 0usize;
715    loop {
716        inner.skip_sp();
717        match inner.peek() {
718            Some(b')') => {
719                inner.bump();
720                break;
721            }
722            None => return None,
723            Some(_) => {}
724        }
725        let _ = item_view(&mut inner)?;
726        count += 1;
727    }
728    let text = c.s.get(start..inner.i).unwrap_or(&[]);
729    let params = params_view(&mut inner)?;
730    *c = inner;
731    Some(Member::InnerList(InnerList {
732        text,
733        count,
734        params,
735    }))
736}
737
738/// The value of a validated field line with its surrounding SP removed.
739fn field_text(v: &[u8]) -> Cursor<'_> {
740    let start = v.iter().take_while(|&&b| b == b' ').count();
741    let end = v.len() - v.iter().rev().take_while(|&&b| b == b' ').count();
742    Cursor::new(v.get(start..end.max(start)).unwrap_or(&[]))
743}
744
745/// Advances past the separator after a member of validated text; `false` at
746/// the end.
747fn next_member(c: &mut Cursor<'_>) -> bool {
748    c.skip_ows();
749    if c.peek() != Some(b',') {
750        return false;
751    }
752    c.bump();
753    c.skip_ows();
754    true
755}
756
757/// A validated List.
758///
759/// # Examples
760///
761/// ```
762/// let list = parse_net::sfv::parse_list(b"a, b;x, (c d)")?;
763/// assert_eq!(list.len(), 3);
764/// # Ok::<(), parse_net::ParseError>(())
765/// ```
766#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
767pub struct List<'a> {
768    text: &'a [u8],
769    count: usize,
770}
771
772impl<'a> List<'a> {
773    /// The members, in order.
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// use parse_net::sfv::{self, BareItem, Member};
779    ///
780    /// let list = sfv::parse_list(b"a, 2")?;
781    /// let mut it = list.iter();
782    /// assert!(matches!(it.next(), Some(Member::Item(i)) if i.bare == BareItem::Token("a")));
783    /// assert!(matches!(it.next(), Some(Member::Item(i)) if i.bare == BareItem::Integer(2)));
784    /// assert!(it.next().is_none());
785    /// # Ok::<(), parse_net::ParseError>(())
786    /// ```
787    #[must_use]
788    pub fn iter(&self) -> ListIter<'a> {
789        ListIter {
790            c: Cursor::new(self.text),
791            started: false,
792        }
793    }
794
795    /// The number of members.
796    ///
797    /// # Examples
798    ///
799    /// ```
800    /// assert_eq!(parse_net::sfv::parse_list(b"a, b, c")?.len(), 3);
801    /// # Ok::<(), parse_net::ParseError>(())
802    /// ```
803    #[must_use]
804    pub const fn len(&self) -> usize {
805        self.count
806    }
807
808    /// Whether the list is empty.
809    ///
810    /// # Examples
811    ///
812    /// ```
813    /// assert!(!parse_net::sfv::parse_list(b"a")?.is_empty());
814    /// # Ok::<(), parse_net::ParseError>(())
815    /// ```
816    #[must_use]
817    pub const fn is_empty(&self) -> bool {
818        self.count == 0
819    }
820}
821
822/// The members of a validated [`List`].
823///
824/// # Examples
825///
826/// ```
827/// use parse_net::sfv::{self, Member};
828///
829/// let list = sfv::parse_list(b"a, (b c), d")?;
830/// let inner = list.iter().filter(|m| matches!(m, Member::InnerList(_))).count();
831/// assert_eq!(inner, 1);
832/// # Ok::<(), parse_net::ParseError>(())
833/// ```
834#[derive(Clone, Debug)]
835pub struct ListIter<'a> {
836    c: Cursor<'a>,
837    started: bool,
838}
839
840impl<'a> Iterator for ListIter<'a> {
841    type Item = Member<'a>;
842
843    fn next(&mut self) -> Option<Member<'a>> {
844        if self.started && !next_member(&mut self.c) {
845            return None;
846        }
847        self.started = true;
848        if self.c.is_empty() {
849            return None;
850        }
851        member_view(&mut self.c)
852    }
853}
854
855/// A validated Dictionary. Every member is kept in order; a repeated key's
856/// last value wins in [`get`](Self::get) and [`index_into`](Self::index_into).
857///
858/// # Examples
859///
860/// ```
861/// use parse_net::sfv::{self, BareItem, Member};
862///
863/// let d = sfv::parse_dictionary(b"a=1, b")?;
864/// assert_eq!(d.len(), 2);
865/// assert!(matches!(d.get("b"), Some(Member::Item(i)) if i.bare == BareItem::Boolean(true)));
866/// # Ok::<(), parse_net::ParseError>(())
867/// ```
868#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
869pub struct Dictionary<'a> {
870    text: &'a [u8],
871    count: usize,
872}
873
874impl<'a> Dictionary<'a> {
875    /// The members with their keys, in order (repeats included).
876    ///
877    /// # Examples
878    ///
879    /// ```
880    /// use parse_net::sfv;
881    ///
882    /// let d = sfv::parse_dictionary(b"a=1, b=2, a=3")?;
883    /// assert!(d.iter().map(|(k, _)| k).eq(["a", "b", "a"]));
884    /// # Ok::<(), parse_net::ParseError>(())
885    /// ```
886    #[must_use]
887    pub fn iter(&self) -> DictIter<'a> {
888        DictIter {
889            c: Cursor::new(self.text),
890            started: false,
891        }
892    }
893
894    /// The member for `key`: the last occurrence.
895    ///
896    /// # Examples
897    ///
898    /// ```
899    /// use parse_net::sfv::{self, BareItem, Member};
900    ///
901    /// let d = sfv::parse_dictionary(b"a=1, b=(x y)")?;
902    /// assert!(matches!(d.get("b"), Some(Member::InnerList(l)) if l.len() == 2));
903    /// assert!(d.get("c").is_none());
904    /// # Ok::<(), parse_net::ParseError>(())
905    /// ```
906    #[must_use]
907    pub fn get(&self, key: &str) -> Option<Member<'a>> {
908        self.iter()
909            .filter(|(k, _)| *k == key)
910            .last()
911            .map(|(_, m)| m)
912    }
913
914    /// Fills `slots` with one entry per distinct key (the last value for a
915    /// repeated key), in first-seen order, and returns the filled part: for
916    /// callers that look up many keys.
917    ///
918    /// # Errors
919    ///
920    /// [`ErrorKind::BufferTooSmall`] when there are more distinct keys than
921    /// slots.
922    ///
923    /// # Examples
924    ///
925    /// ```
926    /// use parse_net::sfv::{self, BareItem, Item, Member};
927    ///
928    /// let d = sfv::parse_dictionary(b"a=1, b=2, a=3")?;
929    /// let mut slots = [("", Member::Item(Item::new(BareItem::Boolean(false)))); 4];
930    /// let index = d.index_into(&mut slots)?;
931    /// assert_eq!(index.len(), 2);
932    /// assert!(matches!(index[0], ("a", Member::Item(i)) if i.bare == BareItem::Integer(3)));
933    /// # Ok::<(), parse_net::ParseError>(())
934    /// ```
935    pub fn index_into<'i>(
936        &self,
937        slots: &'i mut [(&'a str, Member<'a>)],
938    ) -> Result<&'i [(&'a str, Member<'a>)]> {
939        let mut n = 0usize;
940        for (k, m) in self.iter() {
941            let existing = slots
942                .get_mut(..n)
943                .and_then(|filled| filled.iter_mut().find(|(sk, _)| *sk == k));
944            match existing {
945                Some(slot) => slot.1 = m,
946                None => {
947                    let Some(slot) = slots.get_mut(n) else {
948                        return err(ErrorKind::BufferTooSmall, 0);
949                    };
950                    *slot = (k, m);
951                    n += 1;
952                }
953            }
954        }
955        Ok(slots.get(..n).unwrap_or(&[]))
956    }
957
958    /// The number of members, repeats included.
959    ///
960    /// # Examples
961    ///
962    /// ```
963    /// assert_eq!(parse_net::sfv::parse_dictionary(b"a=1, a=2")?.len(), 2);
964    /// # Ok::<(), parse_net::ParseError>(())
965    /// ```
966    #[must_use]
967    pub const fn len(&self) -> usize {
968        self.count
969    }
970
971    /// Whether the dictionary is empty.
972    ///
973    /// # Examples
974    ///
975    /// ```
976    /// assert!(!parse_net::sfv::parse_dictionary(b"a")?.is_empty());
977    /// # Ok::<(), parse_net::ParseError>(())
978    /// ```
979    #[must_use]
980    pub const fn is_empty(&self) -> bool {
981        self.count == 0
982    }
983}
984
985/// The members of a validated [`Dictionary`].
986///
987/// # Examples
988///
989/// ```
990/// use parse_net::sfv::{self, BareItem, Member};
991///
992/// let d = sfv::parse_dictionary(b"u=1, i")?;
993/// let mut it = d.iter();
994/// assert!(matches!(it.next(), Some(("u", Member::Item(i))) if i.bare == BareItem::Integer(1)));
995/// assert!(matches!(it.next(), Some(("i", Member::Item(i))) if i.bare == BareItem::Boolean(true)));
996/// assert!(it.next().is_none());
997/// # Ok::<(), parse_net::ParseError>(())
998/// ```
999#[derive(Clone, Debug)]
1000pub struct DictIter<'a> {
1001    c: Cursor<'a>,
1002    started: bool,
1003}
1004
1005impl<'a> Iterator for DictIter<'a> {
1006    type Item = (&'a str, Member<'a>);
1007
1008    fn next(&mut self) -> Option<Self::Item> {
1009        if self.started && !next_member(&mut self.c) {
1010            return None;
1011        }
1012        self.started = true;
1013        if self.c.is_empty() {
1014            return None;
1015        }
1016        let k = parse::key(&mut self.c, &RELAXED).ok()?;
1017        let m = if self.c.peek() == Some(b'=') {
1018            self.c.bump();
1019            member_view(&mut self.c)?
1020        } else {
1021            Member::Item(Item {
1022                bare: BareItem::Boolean(true),
1023                params: params_view(&mut self.c)?,
1024            })
1025        };
1026        Some((k, m))
1027    }
1028}
1029
1030/// Several field lines read as one List.
1031///
1032/// # Examples
1033///
1034/// ```
1035/// let lines: [&[u8]; 2] = [b"a", b"b, c"];
1036/// let list = parse_net::sfv::parse_list_lines(&lines)?;
1037/// assert_eq!(list.len(), 3);
1038/// # Ok::<(), parse_net::ParseError>(())
1039/// ```
1040#[derive(Clone, Copy, Debug)]
1041pub struct ListLines<'a> {
1042    lines: &'a [&'a [u8]],
1043    count: usize,
1044}
1045
1046impl<'a> ListLines<'a> {
1047    /// The members of every line, in order.
1048    ///
1049    /// # Examples
1050    ///
1051    /// ```
1052    /// use parse_net::sfv::{self, BareItem, Member};
1053    ///
1054    /// let lines: [&[u8]; 2] = [b"a", b"b"];
1055    /// let list = sfv::parse_list_lines(&lines)?;
1056    /// let mut it = list.iter();
1057    /// assert!(matches!(it.next(), Some(Member::Item(i)) if i.bare == BareItem::Token("a")));
1058    /// assert!(matches!(it.next(), Some(Member::Item(i)) if i.bare == BareItem::Token("b")));
1059    /// assert!(it.next().is_none());
1060    /// # Ok::<(), parse_net::ParseError>(())
1061    /// ```
1062    pub fn iter(&self) -> impl Iterator<Item = Member<'a>> + use<'a> {
1063        self.lines.iter().flat_map(|l| ListIter {
1064            c: field_text(l),
1065            started: false,
1066        })
1067    }
1068
1069    /// The number of members across every line.
1070    ///
1071    /// # Examples
1072    ///
1073    /// ```
1074    /// let lines: [&[u8]; 3] = [b"a, b", b"c", b"d, e"];
1075    /// assert_eq!(parse_net::sfv::parse_list_lines(&lines)?.len(), 5);
1076    /// # Ok::<(), parse_net::ParseError>(())
1077    /// ```
1078    #[must_use]
1079    pub const fn len(&self) -> usize {
1080        self.count
1081    }
1082
1083    /// Whether no line has a member.
1084    ///
1085    /// # Examples
1086    ///
1087    /// ```
1088    /// let lines: [&[u8]; 1] = [b"a"];
1089    /// assert!(!parse_net::sfv::parse_list_lines(&lines)?.is_empty());
1090    /// # Ok::<(), parse_net::ParseError>(())
1091    /// ```
1092    #[must_use]
1093    pub const fn is_empty(&self) -> bool {
1094        self.count == 0
1095    }
1096}
1097
1098/// Several field lines read as one Dictionary.
1099///
1100/// # Examples
1101///
1102/// ```
1103/// use parse_net::sfv::{self, BareItem, Member};
1104///
1105/// let lines: [&[u8]; 2] = [b"a=1", b"b=2, a=3"];
1106/// let d = sfv::parse_dictionary_lines(&lines)?;
1107/// assert_eq!(d.len(), 3);
1108/// assert!(matches!(d.get("a"), Some(Member::Item(i)) if i.bare == BareItem::Integer(3)));
1109/// # Ok::<(), parse_net::ParseError>(())
1110/// ```
1111#[derive(Clone, Copy, Debug)]
1112pub struct DictionaryLines<'a> {
1113    lines: &'a [&'a [u8]],
1114    count: usize,
1115}
1116
1117impl<'a> DictionaryLines<'a> {
1118    /// The members of every line, in order.
1119    ///
1120    /// # Examples
1121    ///
1122    /// ```
1123    /// let lines: [&[u8]; 2] = [b"a=1", b"b=2, a=3"];
1124    /// let d = parse_net::sfv::parse_dictionary_lines(&lines)?;
1125    /// assert!(d.iter().map(|(k, _)| k).eq(["a", "b", "a"]));
1126    /// # Ok::<(), parse_net::ParseError>(())
1127    /// ```
1128    pub fn iter(&self) -> impl Iterator<Item = (&'a str, Member<'a>)> + use<'a> {
1129        self.lines.iter().flat_map(|l| DictIter {
1130            c: field_text(l),
1131            started: false,
1132        })
1133    }
1134
1135    /// The member for `key`: the last occurrence across every line.
1136    ///
1137    /// # Examples
1138    ///
1139    /// ```
1140    /// use parse_net::sfv::{self, BareItem, Member};
1141    ///
1142    /// let lines: [&[u8]; 2] = [b"a=1, b", b"a=2"];
1143    /// let d = sfv::parse_dictionary_lines(&lines)?;
1144    /// assert!(matches!(d.get("a"), Some(Member::Item(i)) if i.bare == BareItem::Integer(2)));
1145    /// assert!(d.get("c").is_none());
1146    /// # Ok::<(), parse_net::ParseError>(())
1147    /// ```
1148    #[must_use]
1149    pub fn get(&self, key: &str) -> Option<Member<'a>> {
1150        self.iter()
1151            .filter(|(k, _)| *k == key)
1152            .last()
1153            .map(|(_, m)| m)
1154    }
1155
1156    /// The number of members across every line, repeats included.
1157    ///
1158    /// # Examples
1159    ///
1160    /// ```
1161    /// let lines: [&[u8]; 2] = [b"a=1, b", b"a=2"];
1162    /// assert_eq!(parse_net::sfv::parse_dictionary_lines(&lines)?.len(), 3);
1163    /// # Ok::<(), parse_net::ParseError>(())
1164    /// ```
1165    #[must_use]
1166    pub const fn len(&self) -> usize {
1167        self.count
1168    }
1169
1170    /// Whether no line has a member.
1171    ///
1172    /// # Examples
1173    ///
1174    /// ```
1175    /// let lines: [&[u8]; 1] = [b"a"];
1176    /// assert!(!parse_net::sfv::parse_dictionary_lines(&lines)?.is_empty());
1177    /// # Ok::<(), parse_net::ParseError>(())
1178    /// ```
1179    #[must_use]
1180    pub const fn is_empty(&self) -> bool {
1181        self.count == 0
1182    }
1183}
1184
1185/// Receives a parse as events: the single-pass form, for callers that read
1186/// one key or count items without building a view.
1187///
1188/// # Examples
1189///
1190/// ```
1191/// use parse_net::{sfv::{BareItem, Parser, Visitor}, Limits, ParseError};
1192///
1193/// struct Urgency(Option<i64>, bool);
1194/// impl<'a> Visitor<'a> for Urgency {
1195///     fn item(&mut self, bare: BareItem<'a>) -> Result<(), ParseError> {
1196///         if let (true, BareItem::Integer(u)) = (self.1, bare) { self.0 = Some(u); }
1197///         Ok(())
1198///     }
1199///     fn param(&mut self, _: &'a str, _: BareItem<'a>) -> Result<(), ParseError> { Ok(()) }
1200///     fn key(&mut self, key: &'a str) -> Result<(), ParseError> { self.1 = key == "u"; Ok(()) }
1201/// }
1202///
1203/// let mut v = Urgency(None, false);
1204/// Parser::new(Limits::DEFAULT).visit_dictionary(b"u=5, i", &mut v)?;
1205/// assert_eq!(v.0, Some(5));
1206/// # Ok::<(), ParseError>(())
1207/// ```
1208pub trait Visitor<'a> {
1209    /// A bare item: a member, an inner-list item, or a dictionary value.
1210    ///
1211    /// # Errors
1212    ///
1213    /// Any error stops the parse and is returned.
1214    fn item(&mut self, bare: BareItem<'a>) -> Result<()>;
1215
1216    /// A parameter of the most recent item or inner list.
1217    ///
1218    /// # Errors
1219    ///
1220    /// Any error stops the parse and is returned.
1221    fn param(&mut self, key: &'a str, value: BareItem<'a>) -> Result<()>;
1222
1223    /// An inner list begins.
1224    ///
1225    /// # Errors
1226    ///
1227    /// Any error stops the parse and is returned.
1228    fn inner_list_start(&mut self) -> Result<()> {
1229        Ok(())
1230    }
1231
1232    /// An inner list ends (its parameters follow).
1233    ///
1234    /// # Errors
1235    ///
1236    /// Any error stops the parse and is returned.
1237    fn inner_list_end(&mut self) -> Result<()> {
1238        Ok(())
1239    }
1240
1241    /// A dictionary key; its value follows.
1242    ///
1243    /// # Errors
1244    ///
1245    /// Any error stops the parse and is returned.
1246    fn key(&mut self, key: &'a str) -> Result<()> {
1247        let _ = key;
1248        Ok(())
1249    }
1250}
1251
1252struct VisitorEvents<'v, V>(&'v mut V);
1253
1254impl<'a, V: Visitor<'a>> Events<'a> for VisitorEvents<'_, V> {
1255    fn item(&mut self, bare: BareItem<'a>) -> Result<()> {
1256        self.0.item(bare)
1257    }
1258    fn param(&mut self, key: &'a str, value: BareItem<'a>) -> Result<()> {
1259        self.0.param(key, value)
1260    }
1261    fn inner_start(&mut self) -> Result<()> {
1262        self.0.inner_list_start()
1263    }
1264    fn inner_end(&mut self) -> Result<()> {
1265        self.0.inner_list_end()
1266    }
1267    fn key(&mut self, key: &'a str) -> Result<()> {
1268        self.0.key(key)
1269    }
1270}
1271
1272/// The configurable parser.
1273///
1274/// # Examples
1275///
1276/// ```
1277/// use parse_net::{sfv::Parser, ErrorKind, Limits};
1278///
1279/// let strict = Parser::new(Limits::DEFAULT.max_list_members(2));
1280/// assert_eq!(strict.list(b"a, b, c").unwrap_err().kind(), ErrorKind::TooManyMembers);
1281/// assert_eq!(Parser::default().list(b"a, b, c")?.len(), 3);
1282/// # Ok::<(), parse_net::ParseError>(())
1283/// ```
1284#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1285pub struct Parser {
1286    limits: Limits,
1287}
1288
1289impl Default for Parser {
1290    fn default() -> Self {
1291        Self::new(Limits::DEFAULT)
1292    }
1293}
1294
1295impl Parser {
1296    /// A parser with `limits`.
1297    ///
1298    /// # Examples
1299    ///
1300    /// ```
1301    /// use parse_net::{sfv::Parser, Limits};
1302    ///
1303    /// let p = Parser::new(Limits::DEFAULT.max_dictionary_members(1));
1304    /// assert!(p.dictionary(b"a").is_ok());
1305    /// assert!(p.dictionary(b"a, b").is_err());
1306    /// # Ok::<(), parse_net::ParseError>(())
1307    /// ```
1308    #[must_use]
1309    pub const fn new(limits: Limits) -> Self {
1310        Self { limits }
1311    }
1312
1313    /// Parses an Item (section 4.2.3).
1314    ///
1315    /// # Errors
1316    ///
1317    /// See [`parse_item`].
1318    ///
1319    /// # Examples
1320    ///
1321    /// ```
1322    /// use parse_net::sfv::{BareItem, Parser};
1323    ///
1324    /// let item = Parser::default().item(b"?0;x")?;
1325    /// assert_eq!(item.bare, BareItem::Boolean(false));
1326    /// assert_eq!(item.params.len(), 1);
1327    /// # Ok::<(), parse_net::ParseError>(())
1328    /// ```
1329    pub fn item<'a>(&self, v: &'a [u8]) -> Result<Item<'a>> {
1330        let l = self.limits;
1331        let ((bare, params), _, _) = parse::field(v, |c| {
1332            let bare = parse::bare_item(c, &l)?;
1333            let start = c.i;
1334            let count = parse::params(c, &l, |_, _| Ok(()))?;
1335            Ok((
1336                bare,
1337                SfParams {
1338                    text: c.s.get(start..c.i).unwrap_or(&[]),
1339                    count,
1340                },
1341            ))
1342        })?;
1343        Ok(Item { bare, params })
1344    }
1345
1346    /// Parses a List (section 4.2.1).
1347    ///
1348    /// # Errors
1349    ///
1350    /// See [`parse_list`].
1351    ///
1352    /// # Examples
1353    ///
1354    /// ```
1355    /// use parse_net::sfv::Parser;
1356    ///
1357    /// assert_eq!(Parser::default().list(b"a, (b c);q=1")?.len(), 2);
1358    /// assert!(Parser::default().list(b"a,,b").is_err());
1359    /// # Ok::<(), parse_net::ParseError>(())
1360    /// ```
1361    pub fn list<'a>(&self, v: &'a [u8]) -> Result<List<'a>> {
1362        let l = self.limits;
1363        let (count, start, end) = parse::field(v, |c| parse::list(c, &l, &mut Nothing))?;
1364        Ok(List {
1365            text: v.get(start..end).unwrap_or(&[]),
1366            count,
1367        })
1368    }
1369
1370    /// Parses a Dictionary (section 4.2.2).
1371    ///
1372    /// # Errors
1373    ///
1374    /// See [`parse_dictionary`].
1375    ///
1376    /// # Examples
1377    ///
1378    /// ```
1379    /// use parse_net::sfv::{BareItem, Member, Parser};
1380    ///
1381    /// let d = Parser::default().dictionary(b"a=1, b")?;
1382    /// assert!(matches!(d.get("a"), Some(Member::Item(i)) if i.bare == BareItem::Integer(1)));
1383    /// # Ok::<(), parse_net::ParseError>(())
1384    /// ```
1385    pub fn dictionary<'a>(&self, v: &'a [u8]) -> Result<Dictionary<'a>> {
1386        let l = self.limits;
1387        let (count, start, end) = parse::field(v, |c| parse::dictionary(c, &l, &mut Nothing))?;
1388        Ok(Dictionary {
1389            text: v.get(start..end).unwrap_or(&[]),
1390            count,
1391        })
1392    }
1393
1394    /// Parses several field lines as one List: each line must parse on its
1395    /// own, an empty line fails the field, and the member limit counts
1396    /// across lines.
1397    ///
1398    /// # Errors
1399    ///
1400    /// As [`list`](Self::list), with [`ParseError::line`] set; an empty line
1401    /// is [`ErrorKind::Empty`].
1402    ///
1403    /// # Examples
1404    ///
1405    /// ```
1406    /// use parse_net::{sfv::Parser, ErrorKind};
1407    ///
1408    /// let good: [&[u8]; 2] = [b"a", b"b, c"];
1409    /// assert_eq!(Parser::default().list_lines(&good)?.len(), 3);
1410    /// let bad: [&[u8]; 2] = [b"a", b""];
1411    /// let e = Parser::default().list_lines(&bad).unwrap_err();
1412    /// assert_eq!((e.kind(), e.line()), (ErrorKind::Empty, 1));
1413    /// # Ok::<(), parse_net::ParseError>(())
1414    /// ```
1415    pub fn list_lines<'a>(&self, lines: &'a [&'a [u8]]) -> Result<ListLines<'a>> {
1416        let mut count = 0usize;
1417        for (n, line) in lines.iter().enumerate() {
1418            if line.iter().all(|&b| b == b' ') {
1419                return Err(ParseError::new(ErrorKind::Empty, 0).on_line(n));
1420            }
1421            count += self.list(line).map_err(|e| e.on_line(n))?.len();
1422            if count > usize::from(self.limits.list_members) {
1423                return Err(ParseError::new(ErrorKind::TooManyMembers, 0).on_line(n));
1424            }
1425        }
1426        Ok(ListLines { lines, count })
1427    }
1428
1429    /// Parses several field lines as one Dictionary (the last value of a
1430    /// repeated key wins across lines).
1431    ///
1432    /// # Errors
1433    ///
1434    /// As [`list_lines`](Self::list_lines).
1435    ///
1436    /// # Examples
1437    ///
1438    /// ```
1439    /// use parse_net::sfv::{BareItem, Member, Parser};
1440    ///
1441    /// let lines: [&[u8]; 2] = [b"a=1", b"a=2"];
1442    /// let d = Parser::default().dictionary_lines(&lines)?;
1443    /// assert!(matches!(d.get("a"), Some(Member::Item(i)) if i.bare == BareItem::Integer(2)));
1444    /// # Ok::<(), parse_net::ParseError>(())
1445    /// ```
1446    pub fn dictionary_lines<'a>(&self, lines: &'a [&'a [u8]]) -> Result<DictionaryLines<'a>> {
1447        let mut count = 0usize;
1448        for (n, line) in lines.iter().enumerate() {
1449            if line.iter().all(|&b| b == b' ') {
1450                return Err(ParseError::new(ErrorKind::Empty, 0).on_line(n));
1451            }
1452            count += self.dictionary(line).map_err(|e| e.on_line(n))?.len();
1453            if count > usize::from(self.limits.dictionary_members) {
1454                return Err(ParseError::new(ErrorKind::TooManyMembers, 0).on_line(n));
1455            }
1456        }
1457        Ok(DictionaryLines { lines, count })
1458    }
1459
1460    /// Parses an Item, reporting it to `visitor`.
1461    ///
1462    /// # Errors
1463    ///
1464    /// As [`item`](Self::item), or the visitor's error.
1465    ///
1466    /// # Examples
1467    ///
1468    /// ```
1469    /// use parse_net::{sfv::{BareItem, Parser, Visitor}, Limits, ParseError};
1470    ///
1471    /// struct Count(usize);
1472    /// impl<'a> Visitor<'a> for Count {
1473    ///     fn item(&mut self, _: BareItem<'a>) -> Result<(), ParseError> { Ok(()) }
1474    ///     fn param(&mut self, _: &'a str, _: BareItem<'a>) -> Result<(), ParseError> { self.0 += 1; Ok(()) }
1475    /// }
1476    ///
1477    /// let mut c = Count(0);
1478    /// Parser::new(Limits::DEFAULT).visit_item(b"a;x=1;y", &mut c)?;
1479    /// assert_eq!(c.0, 2);
1480    /// # Ok::<(), ParseError>(())
1481    /// ```
1482    pub fn visit_item<'a, V: Visitor<'a>>(&self, v: &'a [u8], visitor: &mut V) -> Result<()> {
1483        let l = self.limits;
1484        parse::field(v, |c| {
1485            let mut ev = VisitorEvents(visitor);
1486            let bare = parse::bare_item(c, &l)?;
1487            ev.item(bare)?;
1488            parse::params(c, &l, |k, x| ev.param(k, x)).map(|_| ())
1489        })
1490        .map(|_| ())
1491    }
1492
1493    /// Parses a List, reporting it to `visitor`.
1494    ///
1495    /// # Errors
1496    ///
1497    /// As [`list`](Self::list), or the visitor's error.
1498    ///
1499    /// # Examples
1500    ///
1501    /// ```
1502    /// use parse_net::{sfv::{BareItem, Parser, Visitor}, Limits, ParseError};
1503    ///
1504    /// struct Count(usize);
1505    /// impl<'a> Visitor<'a> for Count {
1506    ///     fn item(&mut self, _: BareItem<'a>) -> Result<(), ParseError> { self.0 += 1; Ok(()) }
1507    ///     fn param(&mut self, _: &'a str, _: BareItem<'a>) -> Result<(), ParseError> { Ok(()) }
1508    /// }
1509    ///
1510    /// let mut c = Count(0);
1511    /// Parser::new(Limits::DEFAULT).visit_list(b"a, (b c);q", &mut c)?;
1512    /// assert_eq!(c.0, 3);
1513    /// # Ok::<(), ParseError>(())
1514    /// ```
1515    pub fn visit_list<'a, V: Visitor<'a>>(&self, v: &'a [u8], visitor: &mut V) -> Result<()> {
1516        let l = self.limits;
1517        parse::field(v, |c| parse::list(c, &l, &mut VisitorEvents(visitor))).map(|_| ())
1518    }
1519
1520    /// Parses a Dictionary, reporting it to `visitor`.
1521    ///
1522    /// # Errors
1523    ///
1524    /// As [`dictionary`](Self::dictionary), or the visitor's error.
1525    ///
1526    /// # Examples
1527    ///
1528    /// ```
1529    /// use parse_net::{sfv::{BareItem, Parser, Visitor}, Limits, ParseError};
1530    ///
1531    /// struct Count(usize);
1532    /// impl<'a> Visitor<'a> for Count {
1533    ///     fn item(&mut self, _: BareItem<'a>) -> Result<(), ParseError> { Ok(()) }
1534    ///     fn param(&mut self, _: &'a str, _: BareItem<'a>) -> Result<(), ParseError> { Ok(()) }
1535    ///     fn key(&mut self, _: &'a str) -> Result<(), ParseError> { self.0 += 1; Ok(()) }
1536    /// }
1537    ///
1538    /// let mut c = Count(0);
1539    /// Parser::new(Limits::DEFAULT).visit_dictionary(b"a=1, b, c=(x y)", &mut c)?;
1540    /// assert_eq!(c.0, 3);
1541    /// # Ok::<(), ParseError>(())
1542    /// ```
1543    pub fn visit_dictionary<'a, V: Visitor<'a>>(&self, v: &'a [u8], visitor: &mut V) -> Result<()> {
1544        let l = self.limits;
1545        parse::field(v, |c| parse::dictionary(c, &l, &mut VisitorEvents(visitor))).map(|_| ())
1546    }
1547}
1548
1549/// Parses an Item with the default [`Limits`] (RFC 9651 section 4.2.3).
1550///
1551/// # Errors
1552///
1553/// [`ErrorKind::TrailingData`]; for the bare item:
1554/// [`ErrorKind::InvalidNumber`] (`-` alone, `1.`, a Decimal after `@`),
1555/// [`ErrorKind::NumberOverflow`] (16 digits, 13 integer digits in a Decimal,
1556/// 4 fractional digits), [`ErrorKind::InvalidByte`],
1557/// [`ErrorKind::InvalidQuotedPair`], [`ErrorKind::UnterminatedQuote`],
1558/// [`ErrorKind::InvalidBase64`], [`ErrorKind::InvalidPercentEncoding`]
1559/// (uppercase hex in a Display String), [`ErrorKind::InvalidUtf8`],
1560/// [`ErrorKind::OutOfRange`] (a Date outside years 1 to 9999),
1561/// [`ErrorKind::TooLong`]; for parameters: [`ErrorKind::InvalidKey`],
1562/// [`ErrorKind::TooManyMembers`].
1563///
1564/// # Examples
1565///
1566/// ```
1567/// use parse_net::sfv::{self, BareItem};
1568///
1569/// assert_eq!(sfv::parse_item(b"?1")?.bare, BareItem::Boolean(true));
1570/// assert_eq!(sfv::parse_item(b"@1659578233")?.bare, BareItem::Date(1_659_578_233));
1571/// assert!(sfv::parse_item(b"%\"%C3%A9\"").is_err());
1572/// # Ok::<(), parse_net::ParseError>(())
1573/// ```
1574pub fn parse_item(value: &[u8]) -> Result<Item<'_>> {
1575    Parser::default().item(value)
1576}
1577
1578/// Parses a List with the default [`Limits`] (RFC 9651 section 4.2.1).
1579///
1580/// # Errors
1581///
1582/// As [`parse_item`], and [`ErrorKind::TrailingSeparator`] (`a, b,`),
1583/// [`ErrorKind::ExpectedSeparator`], [`ErrorKind::TooManyMembers`].
1584///
1585/// # Examples
1586///
1587/// ```
1588/// assert_eq!(parse_net::sfv::parse_list(b"a, b,").unwrap_err().kind(), parse_net::ErrorKind::TrailingSeparator);
1589/// ```
1590pub fn parse_list(value: &[u8]) -> Result<List<'_>> {
1591    Parser::default().list(value)
1592}
1593
1594/// Parses a Dictionary with the default [`Limits`] (RFC 9651 section 4.2.2).
1595///
1596/// # Errors
1597///
1598/// As [`parse_list`], and [`ErrorKind::InvalidKey`].
1599///
1600/// # Examples
1601///
1602/// ```
1603/// use parse_net::sfv::{self, BareItem, Member};
1604///
1605/// let d = sfv::parse_dictionary(b"a=1, a=2")?;
1606/// assert!(matches!(d.get("a"), Some(Member::Item(i)) if i.bare == BareItem::Integer(2)));
1607/// # Ok::<(), parse_net::ParseError>(())
1608/// ```
1609pub fn parse_dictionary(value: &[u8]) -> Result<Dictionary<'_>> {
1610    Parser::default().dictionary(value)
1611}
1612
1613/// Parses several field lines as one List with the default [`Limits`].
1614///
1615/// # Errors
1616///
1617/// As [`Parser::list_lines`].
1618///
1619/// # Examples
1620///
1621/// ```
1622/// let lines: [&[u8]; 2] = [b"a, b", b"c"];
1623/// assert_eq!(parse_net::sfv::parse_list_lines(&lines)?.len(), 3);
1624/// # Ok::<(), parse_net::ParseError>(())
1625/// ```
1626pub fn parse_list_lines<'a>(lines: &'a [&'a [u8]]) -> Result<ListLines<'a>> {
1627    Parser::default().list_lines(lines)
1628}
1629
1630/// Parses several field lines as one Dictionary with the default [`Limits`].
1631///
1632/// # Errors
1633///
1634/// As [`Parser::dictionary_lines`].
1635///
1636/// # Examples
1637///
1638/// ```
1639/// use parse_net::sfv::{self, BareItem, Member};
1640///
1641/// let lines: [&[u8]; 2] = [b"u=1", b"i"];
1642/// let d = sfv::parse_dictionary_lines(&lines)?;
1643/// assert_eq!(d.len(), 2);
1644/// assert!(matches!(d.get("i"), Some(Member::Item(i)) if i.bare == BareItem::Boolean(true)));
1645/// # Ok::<(), parse_net::ParseError>(())
1646/// ```
1647pub fn parse_dictionary_lines<'a>(lines: &'a [&'a [u8]]) -> Result<DictionaryLines<'a>> {
1648    Parser::default().dictionary_lines(lines)
1649}
1650
1651impl<'a> Item<'a> {
1652    /// An item with no parameters (for filling the slots of
1653    /// [`Dictionary::index_into`]).
1654    ///
1655    /// # Examples
1656    ///
1657    /// ```
1658    /// use parse_net::sfv::{BareItem, Item};
1659    ///
1660    /// let item = Item::new(BareItem::Integer(7));
1661    /// assert_eq!(item.bare, BareItem::Integer(7));
1662    /// assert!(item.params.is_empty());
1663    /// ```
1664    #[must_use]
1665    pub const fn new(bare: BareItem<'a>) -> Self {
1666        Self {
1667            bare,
1668            params: SfParams::EMPTY,
1669        }
1670    }
1671}
1672
1673#[cfg(test)]
1674mod tests;