1#![cfg_attr(
23 feature = "parsed-types",
24 doc = r##"
25### Parsing
26
27```
28# use sfv::{Dictionary, Item, List, Parser};
29# fn main() -> Result<(), sfv::Error> {
30// Parsing a structured field value of Item type.
31let input = "12.445;foo=bar";
32let item: Item = Parser::new(input).parse()?;
33println!("{:#?}", item);
34
35// Parsing a structured field value of List type.
36let input = r#"1;a=tok, ("foo" "bar");baz, ()"#;
37let list: List = Parser::new(input).parse()?;
38println!("{:#?}", list);
39
40// Parsing a structured field value of Dictionary type.
41let input = "a=?0, b, c; foo=bar, rating=1.5, fruits=(apple pear)";
42let dict: Dictionary = Parser::new(input).parse()?;
43println!("{:#?}", dict);
44# Ok(())
45# }
46```
47
48### Getting Parsed Value Members
49```
50# use sfv::*;
51# fn main() -> Result<(), sfv::Error> {
52let input = "u=2, n=(* foo 2)";
53let dict: Dictionary = Parser::new(input).parse()?;
54
55match dict.get("u") {
56 Some(ListEntry::Item(item)) => match &item.bare_item {
57 BareItem::Token(val) => { /* ... */ }
58 BareItem::Integer(val) => { /* ... */ }
59 BareItem::Boolean(val) => { /* ... */ }
60 BareItem::Decimal(val) => { /* ... */ }
61 BareItem::String(val) => { /* ... */ }
62 BareItem::ByteSequence(val) => { /* ... */ }
63 BareItem::Date(val) => { /* ... */ }
64 BareItem::DisplayString(val) => { /* ... */ }
65 },
66 Some(ListEntry::InnerList(inner_list)) => { /* ... */ }
67 None => { /* ... */ }
68}
69# Ok(())
70# }
71```
72"##
73)]
74#![deny(missing_docs)]
154#![deny(missing_debug_implementations)]
155
156mod date;
157mod decimal;
158mod error;
159mod integer;
160mod key;
161#[cfg(feature = "parsed-types")]
162mod parsed;
163mod parser;
164mod ref_serializer;
165mod serializer;
166mod string;
167mod token;
168mod utils;
169pub mod visitor;
170
171#[cfg(test)]
172mod test_decimal;
173#[cfg(test)]
174mod test_integer;
175#[cfg(test)]
176mod test_key;
177#[cfg(test)]
178mod test_parser;
179#[cfg(test)]
180mod test_ref_serializer;
181#[cfg(test)]
182mod test_serializer;
183#[cfg(test)]
184mod test_string;
185#[cfg(test)]
186mod test_token;
187
188use std::borrow::{Borrow, Cow};
189use std::fmt;
190use std::string::String as StdString;
191
192pub use date::Date;
193pub use decimal::Decimal;
194pub use error::Error;
195pub use integer::{integer, Integer};
196pub use key::{key_ref, Key, KeyRef};
197#[cfg(feature = "parsed-types")]
198pub use parsed::{Dictionary, FieldType, InnerList, Item, List, ListEntry, Parameters};
199pub use parser::Parser;
200pub use ref_serializer::{
201 DictSerializer, InnerListSerializer, ItemSerializer, ListSerializer, ParameterSerializer,
202};
203pub use string::{string_ref, String, StringRef};
204pub use token::{token_ref, Token, TokenRef};
205
206type SFVResult<T> = std::result::Result<T, Error>;
207
208#[derive(Debug, Clone, Copy)]
217#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
218pub enum GenericBareItem<S, B, T, D> {
219 Decimal(Decimal),
222 Integer(Integer),
225 String(S),
231 ByteSequence(B),
235 Boolean(bool),
239 Token(T),
242 Date(Date),
248 DisplayString(D),
262}
263
264impl<S, B, T, D> GenericBareItem<S, B, T, D> {
265 #[must_use]
267 pub fn as_decimal(&self) -> Option<Decimal> {
268 match *self {
269 Self::Decimal(val) => Some(val),
270 _ => None,
271 }
272 }
273
274 #[must_use]
276 pub fn as_integer(&self) -> Option<Integer> {
277 match *self {
278 Self::Integer(val) => Some(val),
279 _ => None,
280 }
281 }
282
283 #[must_use]
285 pub fn as_string(&self) -> Option<&StringRef>
286 where
287 S: Borrow<StringRef>,
288 {
289 match *self {
290 Self::String(ref val) => Some(val.borrow()),
291 _ => None,
292 }
293 }
294
295 #[must_use]
297 pub fn as_byte_sequence(&self) -> Option<&[u8]>
298 where
299 B: Borrow<[u8]>,
300 {
301 match *self {
302 Self::ByteSequence(ref val) => Some(val.borrow()),
303 _ => None,
304 }
305 }
306
307 #[must_use]
309 pub fn as_boolean(&self) -> Option<bool> {
310 match *self {
311 Self::Boolean(val) => Some(val),
312 _ => None,
313 }
314 }
315
316 #[must_use]
318 pub fn as_token(&self) -> Option<&TokenRef>
319 where
320 T: Borrow<TokenRef>,
321 {
322 match *self {
323 Self::Token(ref val) => Some(val.borrow()),
324 _ => None,
325 }
326 }
327
328 #[must_use]
330 pub fn as_date(&self) -> Option<Date> {
331 match *self {
332 Self::Date(val) => Some(val),
333 _ => None,
334 }
335 }
336
337 #[must_use]
339 pub fn as_display_string(&self) -> Option<&D> {
340 match *self {
341 Self::DisplayString(ref val) => Some(val),
342 _ => None,
343 }
344 }
345}
346
347impl<S, B, T, D> From<Integer> for GenericBareItem<S, B, T, D> {
348 fn from(val: Integer) -> Self {
349 Self::Integer(val)
350 }
351}
352
353impl<S, B, T, D> From<bool> for GenericBareItem<S, B, T, D> {
354 fn from(val: bool) -> Self {
355 Self::Boolean(val)
356 }
357}
358
359impl<S, B, T, D> From<Decimal> for GenericBareItem<S, B, T, D> {
360 fn from(val: Decimal) -> Self {
361 Self::Decimal(val)
362 }
363}
364
365impl<S, B, T, D> From<Date> for GenericBareItem<S, B, T, D> {
366 fn from(val: Date) -> Self {
367 Self::Date(val)
368 }
369}
370
371impl<S, B, T, D> TryFrom<f32> for GenericBareItem<S, B, T, D> {
372 type Error = Error;
373
374 fn try_from(val: f32) -> Result<Self, Error> {
375 Decimal::try_from(val).map(Self::Decimal)
376 }
377}
378
379impl<S, B, T, D> TryFrom<f64> for GenericBareItem<S, B, T, D> {
380 type Error = Error;
381
382 fn try_from(val: f64) -> Result<Self, Error> {
383 Decimal::try_from(val).map(Self::Decimal)
384 }
385}
386
387impl<S, T, D> From<Vec<u8>> for GenericBareItem<S, Vec<u8>, T, D> {
388 fn from(val: Vec<u8>) -> Self {
389 Self::ByteSequence(val)
390 }
391}
392
393impl<S, B, D> From<Token> for GenericBareItem<S, B, Token, D> {
394 fn from(val: Token) -> Self {
395 Self::Token(val)
396 }
397}
398
399impl<B, T, D> From<String> for GenericBareItem<String, B, T, D> {
400 fn from(val: String) -> Self {
401 Self::String(val)
402 }
403}
404
405impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, Vec<u8>, T, D> {
406 fn from(val: &'a [u8]) -> Self {
407 Self::ByteSequence(val.to_owned())
408 }
409}
410
411impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, Token, D> {
412 fn from(val: &'a TokenRef) -> Self {
413 Self::Token(val.to_owned())
414 }
415}
416
417impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<String, B, T, D> {
418 fn from(val: &'a StringRef) -> Self {
419 Self::String(val.to_owned())
420 }
421}
422
423#[derive(Debug, PartialEq)]
424pub(crate) enum Num {
425 Decimal(Decimal),
426 Integer(Integer),
427}
428
429#[cfg_attr(
433 feature = "parsed-types",
434 doc = "Used to construct an [`Item`] or [`Parameters`] values."
435)]
436pub type BareItem = GenericBareItem<String, Vec<u8>, Token, StdString>;
453
454pub type RefBareItem<'a> = GenericBareItem<&'a StringRef, &'a [u8], &'a TokenRef, &'a str>;
476
477pub type BareItemFromInput<'a> =
501 GenericBareItem<Cow<'a, StringRef>, Vec<u8>, &'a TokenRef, Cow<'a, str>>;
502
503impl<'a, S, B, T, D> From<&'a GenericBareItem<S, B, T, D>> for RefBareItem<'a>
504where
505 S: Borrow<StringRef>,
506 B: Borrow<[u8]>,
507 T: Borrow<TokenRef>,
508 D: Borrow<str>,
509{
510 fn from(val: &'a GenericBareItem<S, B, T, D>) -> RefBareItem<'a> {
511 match val {
512 GenericBareItem::Integer(val) => RefBareItem::Integer(*val),
513 GenericBareItem::Decimal(val) => RefBareItem::Decimal(*val),
514 GenericBareItem::String(val) => RefBareItem::String(val.borrow()),
515 GenericBareItem::ByteSequence(val) => RefBareItem::ByteSequence(val.borrow()),
516 GenericBareItem::Boolean(val) => RefBareItem::Boolean(*val),
517 GenericBareItem::Token(val) => RefBareItem::Token(val.borrow()),
518 GenericBareItem::Date(val) => RefBareItem::Date(*val),
519 GenericBareItem::DisplayString(val) => RefBareItem::DisplayString(val.borrow()),
520 }
521 }
522}
523
524impl<'a> From<BareItemFromInput<'a>> for BareItem {
525 fn from(val: BareItemFromInput<'a>) -> BareItem {
526 match val {
527 BareItemFromInput::Integer(val) => BareItem::Integer(val),
528 BareItemFromInput::Decimal(val) => BareItem::Decimal(val),
529 BareItemFromInput::String(val) => BareItem::String(val.into_owned()),
530 BareItemFromInput::ByteSequence(val) => BareItem::ByteSequence(val),
531 BareItemFromInput::Boolean(val) => BareItem::Boolean(val),
532 BareItemFromInput::Token(val) => BareItem::Token(val.to_owned()),
533 BareItemFromInput::Date(val) => BareItem::Date(val),
534 BareItemFromInput::DisplayString(val) => BareItem::DisplayString(val.into_owned()),
535 }
536 }
537}
538
539impl<'a> From<RefBareItem<'a>> for BareItem {
540 fn from(val: RefBareItem<'a>) -> BareItem {
541 match val {
542 RefBareItem::Integer(val) => BareItem::Integer(val),
543 RefBareItem::Decimal(val) => BareItem::Decimal(val),
544 RefBareItem::String(val) => BareItem::String(val.to_owned()),
545 RefBareItem::ByteSequence(val) => BareItem::ByteSequence(val.to_owned()),
546 RefBareItem::Boolean(val) => BareItem::Boolean(val),
547 RefBareItem::Token(val) => BareItem::Token(val.to_owned()),
548 RefBareItem::Date(val) => BareItem::Date(val),
549 RefBareItem::DisplayString(val) => BareItem::DisplayString(val.to_owned()),
550 }
551 }
552}
553
554impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, &'a [u8], T, D> {
555 fn from(val: &'a [u8]) -> Self {
556 Self::ByteSequence(val)
557 }
558}
559
560impl<'a, S, B, D> From<&'a Token> for GenericBareItem<S, B, &'a TokenRef, D> {
561 fn from(val: &'a Token) -> Self {
562 Self::Token(val)
563 }
564}
565
566impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, &'a TokenRef, D> {
567 fn from(val: &'a TokenRef) -> Self {
568 Self::Token(val)
569 }
570}
571
572impl<'a, B, T, D> From<&'a String> for GenericBareItem<&'a StringRef, B, T, D> {
573 fn from(val: &'a String) -> Self {
574 Self::String(val)
575 }
576}
577
578impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<&'a StringRef, B, T, D> {
579 fn from(val: &'a StringRef) -> Self {
580 Self::String(val)
581 }
582}
583
584impl<S1, B1, T1, D1, S2, B2, T2, D2> PartialEq<GenericBareItem<S2, B2, T2, D2>>
585 for GenericBareItem<S1, B1, T1, D1>
586where
587 for<'a> RefBareItem<'a>: From<&'a Self>,
588 for<'a> RefBareItem<'a>: From<&'a GenericBareItem<S2, B2, T2, D2>>,
589{
590 fn eq(&self, other: &GenericBareItem<S2, B2, T2, D2>) -> bool {
591 match (RefBareItem::from(self), RefBareItem::from(other)) {
592 (RefBareItem::Integer(a), RefBareItem::Integer(b)) => a == b,
593 (RefBareItem::Decimal(a), RefBareItem::Decimal(b)) => a == b,
594 (RefBareItem::String(a), RefBareItem::String(b)) => a == b,
595 (RefBareItem::ByteSequence(a), RefBareItem::ByteSequence(b)) => a == b,
596 (RefBareItem::Boolean(a), RefBareItem::Boolean(b)) => a == b,
597 (RefBareItem::Token(a), RefBareItem::Token(b)) => a == b,
598 (RefBareItem::Date(a), RefBareItem::Date(b)) => a == b,
599 (RefBareItem::DisplayString(a), RefBareItem::DisplayString(b)) => a == b,
600 _ => false,
601 }
602 }
603}
604
605#[derive(Clone, Copy, Debug, PartialEq, Eq)]
612#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
613pub enum Version {
614 Rfc8941,
618 Rfc9651,
622}
623
624impl fmt::Display for Version {
625 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
626 f.write_str(match self {
627 Self::Rfc8941 => "RFC 8941",
628 Self::Rfc9651 => "RFC 9651",
629 })
630 }
631}
632
633mod private {
634 #[allow(unused)]
635 pub trait Sealed {}
636}