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;