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
155mod date;
156mod decimal;
157mod error;
158mod integer;
159mod key;
160#[cfg(feature = "parsed-types")]
161mod parsed;
162mod parser;
163mod ref_serializer;
164mod serializer;
165mod string;
166mod token;
167mod utils;
168pub mod visitor;
169
170#[cfg(test)]
171mod test_decimal;
172#[cfg(test)]
173mod test_integer;
174#[cfg(test)]
175mod test_key;
176#[cfg(test)]
177mod test_parser;
178#[cfg(test)]
179mod test_ref_serializer;
180#[cfg(test)]
181mod test_serializer;
182#[cfg(test)]
183mod test_string;
184#[cfg(test)]
185mod test_token;
186
187use std::borrow::{Borrow, Cow};
188use std::fmt;
189use std::string::String as StdString;
190
191pub use date::Date;
192pub use decimal::Decimal;
193pub use error::Error;
194pub use integer::{integer, Integer};
195pub use key::{key_ref, Key, KeyRef};
196#[cfg(feature = "parsed-types")]
197pub use parsed::{Dictionary, FieldType, InnerList, Item, List, ListEntry, Parameters};
198pub use parser::Parser;
199pub use ref_serializer::{
200 DictSerializer, InnerListSerializer, ItemSerializer, ListSerializer, ParameterSerializer,
201};
202pub use string::{string_ref, String, StringRef};
203pub use token::{token_ref, Token, TokenRef};
204
205type SFVResult<T> = std::result::Result<T, Error>;
206
207#[derive(Debug, Clone, Copy)]
216#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
217pub enum GenericBareItem<S, B, T, D> {
218 Decimal(Decimal),
221 Integer(Integer),
224 String(S),
230 ByteSequence(B),
234 Boolean(bool),
238 Token(T),
241 Date(Date),
247 DisplayString(D),
261}
262
263impl<S, B, T, D> GenericBareItem<S, B, T, D> {
264 #[must_use]
266 pub fn as_decimal(&self) -> Option<Decimal> {
267 match *self {
268 Self::Decimal(val) => Some(val),
269 _ => None,
270 }
271 }
272
273 #[must_use]
275 pub fn as_integer(&self) -> Option<Integer> {
276 match *self {
277 Self::Integer(val) => Some(val),
278 _ => None,
279 }
280 }
281
282 #[must_use]
284 pub fn as_string(&self) -> Option<&StringRef>
285 where
286 S: Borrow<StringRef>,
287 {
288 match *self {
289 Self::String(ref val) => Some(val.borrow()),
290 _ => None,
291 }
292 }
293
294 #[must_use]
296 pub fn as_byte_sequence(&self) -> Option<&[u8]>
297 where
298 B: Borrow<[u8]>,
299 {
300 match *self {
301 Self::ByteSequence(ref val) => Some(val.borrow()),
302 _ => None,
303 }
304 }
305
306 #[must_use]
308 pub fn as_boolean(&self) -> Option<bool> {
309 match *self {
310 Self::Boolean(val) => Some(val),
311 _ => None,
312 }
313 }
314
315 #[must_use]
317 pub fn as_token(&self) -> Option<&TokenRef>
318 where
319 T: Borrow<TokenRef>,
320 {
321 match *self {
322 Self::Token(ref val) => Some(val.borrow()),
323 _ => None,
324 }
325 }
326
327 #[must_use]
329 pub fn as_date(&self) -> Option<Date> {
330 match *self {
331 Self::Date(val) => Some(val),
332 _ => None,
333 }
334 }
335
336 #[must_use]
338 pub fn as_display_string(&self) -> Option<&D> {
339 match *self {
340 Self::DisplayString(ref val) => Some(val),
341 _ => None,
342 }
343 }
344}
345
346impl<S, B, T, D> From<Integer> for GenericBareItem<S, B, T, D> {
347 fn from(val: Integer) -> Self {
348 Self::Integer(val)
349 }
350}
351
352impl<S, B, T, D> From<bool> for GenericBareItem<S, B, T, D> {
353 fn from(val: bool) -> Self {
354 Self::Boolean(val)
355 }
356}
357
358impl<S, B, T, D> From<Decimal> for GenericBareItem<S, B, T, D> {
359 fn from(val: Decimal) -> Self {
360 Self::Decimal(val)
361 }
362}
363
364impl<S, B, T, D> From<Date> for GenericBareItem<S, B, T, D> {
365 fn from(val: Date) -> Self {
366 Self::Date(val)
367 }
368}
369
370impl<S, B, T, D> TryFrom<f32> for GenericBareItem<S, B, T, D> {
371 type Error = Error;
372
373 fn try_from(val: f32) -> Result<Self, Error> {
374 Decimal::try_from(val).map(Self::Decimal)
375 }
376}
377
378impl<S, B, T, D> TryFrom<f64> for GenericBareItem<S, B, T, D> {
379 type Error = Error;
380
381 fn try_from(val: f64) -> Result<Self, Error> {
382 Decimal::try_from(val).map(Self::Decimal)
383 }
384}
385
386impl<S, T, D> From<Vec<u8>> for GenericBareItem<S, Vec<u8>, T, D> {
387 fn from(val: Vec<u8>) -> Self {
388 Self::ByteSequence(val)
389 }
390}
391
392impl<S, B, D> From<Token> for GenericBareItem<S, B, Token, D> {
393 fn from(val: Token) -> Self {
394 Self::Token(val)
395 }
396}
397
398impl<B, T, D> From<String> for GenericBareItem<String, B, T, D> {
399 fn from(val: String) -> Self {
400 Self::String(val)
401 }
402}
403
404impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, Vec<u8>, T, D> {
405 fn from(val: &'a [u8]) -> Self {
406 Self::ByteSequence(val.to_owned())
407 }
408}
409
410impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, Token, D> {
411 fn from(val: &'a TokenRef) -> Self {
412 Self::Token(val.to_owned())
413 }
414}
415
416impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<String, B, T, D> {
417 fn from(val: &'a StringRef) -> Self {
418 Self::String(val.to_owned())
419 }
420}
421
422#[derive(Debug, PartialEq)]
423pub(crate) enum Num {
424 Decimal(Decimal),
425 Integer(Integer),
426}
427
428#[cfg_attr(
432 feature = "parsed-types",
433 doc = "Used to construct an [`Item`] or [`Parameters`] values."
434)]
435pub type BareItem = GenericBareItem<String, Vec<u8>, Token, StdString>;
452
453pub type RefBareItem<'a> = GenericBareItem<&'a StringRef, &'a [u8], &'a TokenRef, &'a str>;
475
476pub type BareItemFromInput<'a> =
500 GenericBareItem<Cow<'a, StringRef>, Vec<u8>, &'a TokenRef, Cow<'a, str>>;
501
502impl<'a, S, B, T, D> From<&'a GenericBareItem<S, B, T, D>> for RefBareItem<'a>
503where
504 S: Borrow<StringRef>,
505 B: Borrow<[u8]>,
506 T: Borrow<TokenRef>,
507 D: Borrow<str>,
508{
509 fn from(val: &'a GenericBareItem<S, B, T, D>) -> RefBareItem<'a> {
510 match val {
511 GenericBareItem::Integer(val) => RefBareItem::Integer(*val),
512 GenericBareItem::Decimal(val) => RefBareItem::Decimal(*val),
513 GenericBareItem::String(val) => RefBareItem::String(val.borrow()),
514 GenericBareItem::ByteSequence(val) => RefBareItem::ByteSequence(val.borrow()),
515 GenericBareItem::Boolean(val) => RefBareItem::Boolean(*val),
516 GenericBareItem::Token(val) => RefBareItem::Token(val.borrow()),
517 GenericBareItem::Date(val) => RefBareItem::Date(*val),
518 GenericBareItem::DisplayString(val) => RefBareItem::DisplayString(val.borrow()),
519 }
520 }
521}
522
523impl<'a> From<BareItemFromInput<'a>> for BareItem {
524 fn from(val: BareItemFromInput<'a>) -> BareItem {
525 match val {
526 BareItemFromInput::Integer(val) => BareItem::Integer(val),
527 BareItemFromInput::Decimal(val) => BareItem::Decimal(val),
528 BareItemFromInput::String(val) => BareItem::String(val.into_owned()),
529 BareItemFromInput::ByteSequence(val) => BareItem::ByteSequence(val),
530 BareItemFromInput::Boolean(val) => BareItem::Boolean(val),
531 BareItemFromInput::Token(val) => BareItem::Token(val.to_owned()),
532 BareItemFromInput::Date(val) => BareItem::Date(val),
533 BareItemFromInput::DisplayString(val) => BareItem::DisplayString(val.into_owned()),
534 }
535 }
536}
537
538impl<'a> From<RefBareItem<'a>> for BareItem {
539 fn from(val: RefBareItem<'a>) -> BareItem {
540 match val {
541 RefBareItem::Integer(val) => BareItem::Integer(val),
542 RefBareItem::Decimal(val) => BareItem::Decimal(val),
543 RefBareItem::String(val) => BareItem::String(val.to_owned()),
544 RefBareItem::ByteSequence(val) => BareItem::ByteSequence(val.to_owned()),
545 RefBareItem::Boolean(val) => BareItem::Boolean(val),
546 RefBareItem::Token(val) => BareItem::Token(val.to_owned()),
547 RefBareItem::Date(val) => BareItem::Date(val),
548 RefBareItem::DisplayString(val) => BareItem::DisplayString(val.to_owned()),
549 }
550 }
551}
552
553impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, &'a [u8], T, D> {
554 fn from(val: &'a [u8]) -> Self {
555 Self::ByteSequence(val)
556 }
557}
558
559impl<'a, S, B, D> From<&'a Token> for GenericBareItem<S, B, &'a TokenRef, D> {
560 fn from(val: &'a Token) -> Self {
561 Self::Token(val)
562 }
563}
564
565impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, &'a TokenRef, D> {
566 fn from(val: &'a TokenRef) -> Self {
567 Self::Token(val)
568 }
569}
570
571impl<'a, B, T, D> From<&'a String> for GenericBareItem<&'a StringRef, B, T, D> {
572 fn from(val: &'a String) -> Self {
573 Self::String(val)
574 }
575}
576
577impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<&'a StringRef, B, T, D> {
578 fn from(val: &'a StringRef) -> Self {
579 Self::String(val)
580 }
581}
582
583impl<S1, B1, T1, D1, S2, B2, T2, D2> PartialEq<GenericBareItem<S2, B2, T2, D2>>
584 for GenericBareItem<S1, B1, T1, D1>
585where
586 for<'a> RefBareItem<'a>: From<&'a Self>,
587 for<'a> RefBareItem<'a>: From<&'a GenericBareItem<S2, B2, T2, D2>>,
588{
589 fn eq(&self, other: &GenericBareItem<S2, B2, T2, D2>) -> bool {
590 match (RefBareItem::from(self), RefBareItem::from(other)) {
591 (RefBareItem::Integer(a), RefBareItem::Integer(b)) => a == b,
592 (RefBareItem::Decimal(a), RefBareItem::Decimal(b)) => a == b,
593 (RefBareItem::String(a), RefBareItem::String(b)) => a == b,
594 (RefBareItem::ByteSequence(a), RefBareItem::ByteSequence(b)) => a == b,
595 (RefBareItem::Boolean(a), RefBareItem::Boolean(b)) => a == b,
596 (RefBareItem::Token(a), RefBareItem::Token(b)) => a == b,
597 (RefBareItem::Date(a), RefBareItem::Date(b)) => a == b,
598 (RefBareItem::DisplayString(a), RefBareItem::DisplayString(b)) => a == b,
599 _ => false,
600 }
601 }
602}
603
604#[derive(Clone, Copy, Debug, PartialEq, Eq)]
611#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
612pub enum Version {
613 Rfc8941,
617 Rfc9651,
621}
622
623impl fmt::Display for Version {
624 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625 f.write_str(match self {
626 Self::Rfc8941 => "RFC 8941",
627 Self::Rfc9651 => "RFC 9651",
628 })
629 }
630}
631
632mod private {
633 #[allow(unused)]
634 pub trait Sealed {}
635}