#![cfg_attr(
feature = "parsed-types",
doc = r##"
### Parsing
```
# use sfv::{Dictionary, Item, List, Parser};
# fn main() -> Result<(), sfv::Error> {
// Parsing a structured field value of Item type.
let input = "12.445;foo=bar";
let item: Item = Parser::new(input).parse()?;
println!("{:#?}", item);
// Parsing a structured field value of List type.
let input = r#"1;a=tok, ("foo" "bar");baz, ()"#;
let list: List = Parser::new(input).parse()?;
println!("{:#?}", list);
// Parsing a structured field value of Dictionary type.
let input = "a=?0, b, c; foo=bar, rating=1.5, fruits=(apple pear)";
let dict: Dictionary = Parser::new(input).parse()?;
println!("{:#?}", dict);
# Ok(())
# }
```
### Getting Parsed Value Members
```
# use sfv::*;
# fn main() -> Result<(), sfv::Error> {
let input = "u=2, n=(* foo 2)";
let dict: Dictionary = Parser::new(input).parse()?;
match dict.get("u") {
Some(ListEntry::Item(item)) => match &item.bare_item {
BareItem::Token(val) => { /* ... */ }
BareItem::Integer(val) => { /* ... */ }
BareItem::Boolean(val) => { /* ... */ }
BareItem::Decimal(val) => { /* ... */ }
BareItem::String(val) => { /* ... */ }
BareItem::ByteSequence(val) => { /* ... */ }
BareItem::Date(val) => { /* ... */ }
BareItem::DisplayString(val) => { /* ... */ }
},
Some(ListEntry::InnerList(inner_list)) => { /* ... */ }
None => { /* ... */ }
}
# Ok(())
# }
```
"##
)]
#![deny(missing_docs)]
mod date;
mod decimal;
mod error;
mod integer;
mod key;
#[cfg(feature = "parsed-types")]
mod parsed;
mod parser;
mod ref_serializer;
mod serializer;
mod string;
mod token;
mod utils;
pub mod visitor;
#[cfg(test)]
mod test_decimal;
#[cfg(test)]
mod test_integer;
#[cfg(test)]
mod test_key;
#[cfg(test)]
mod test_parser;
#[cfg(test)]
mod test_ref_serializer;
#[cfg(test)]
mod test_serializer;
#[cfg(test)]
mod test_string;
#[cfg(test)]
mod test_token;
use std::borrow::{Borrow, Cow};
use std::fmt;
use std::string::String as StdString;
pub use date::Date;
pub use decimal::Decimal;
pub use error::Error;
pub use integer::{integer, Integer};
pub use key::{key_ref, Key, KeyRef};
#[cfg(feature = "parsed-types")]
pub use parsed::{Dictionary, FieldType, InnerList, Item, List, ListEntry, Parameters};
pub use parser::Parser;
pub use ref_serializer::{
DictSerializer, InnerListSerializer, ItemSerializer, ListSerializer, ParameterSerializer,
};
pub use string::{string_ref, String, StringRef};
pub use token::{token_ref, Token, TokenRef};
type SFVResult<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum GenericBareItem<S, B, T, D> {
Decimal(Decimal),
Integer(Integer),
String(S),
ByteSequence(B),
Boolean(bool),
Token(T),
Date(Date),
DisplayString(D),
}
impl<S, B, T, D> GenericBareItem<S, B, T, D> {
#[must_use]
pub fn as_decimal(&self) -> Option<Decimal> {
match *self {
Self::Decimal(val) => Some(val),
_ => None,
}
}
#[must_use]
pub fn as_integer(&self) -> Option<Integer> {
match *self {
Self::Integer(val) => Some(val),
_ => None,
}
}
#[must_use]
pub fn as_string(&self) -> Option<&StringRef>
where
S: Borrow<StringRef>,
{
match *self {
Self::String(ref val) => Some(val.borrow()),
_ => None,
}
}
#[must_use]
pub fn as_byte_sequence(&self) -> Option<&[u8]>
where
B: Borrow<[u8]>,
{
match *self {
Self::ByteSequence(ref val) => Some(val.borrow()),
_ => None,
}
}
#[must_use]
pub fn as_boolean(&self) -> Option<bool> {
match *self {
Self::Boolean(val) => Some(val),
_ => None,
}
}
#[must_use]
pub fn as_token(&self) -> Option<&TokenRef>
where
T: Borrow<TokenRef>,
{
match *self {
Self::Token(ref val) => Some(val.borrow()),
_ => None,
}
}
#[must_use]
pub fn as_date(&self) -> Option<Date> {
match *self {
Self::Date(val) => Some(val),
_ => None,
}
}
#[must_use]
pub fn as_display_string(&self) -> Option<&D> {
match *self {
Self::DisplayString(ref val) => Some(val),
_ => None,
}
}
}
impl<S, B, T, D> From<Integer> for GenericBareItem<S, B, T, D> {
fn from(val: Integer) -> Self {
Self::Integer(val)
}
}
impl<S, B, T, D> From<bool> for GenericBareItem<S, B, T, D> {
fn from(val: bool) -> Self {
Self::Boolean(val)
}
}
impl<S, B, T, D> From<Decimal> for GenericBareItem<S, B, T, D> {
fn from(val: Decimal) -> Self {
Self::Decimal(val)
}
}
impl<S, B, T, D> From<Date> for GenericBareItem<S, B, T, D> {
fn from(val: Date) -> Self {
Self::Date(val)
}
}
impl<S, B, T, D> TryFrom<f32> for GenericBareItem<S, B, T, D> {
type Error = Error;
fn try_from(val: f32) -> Result<Self, Error> {
Decimal::try_from(val).map(Self::Decimal)
}
}
impl<S, B, T, D> TryFrom<f64> for GenericBareItem<S, B, T, D> {
type Error = Error;
fn try_from(val: f64) -> Result<Self, Error> {
Decimal::try_from(val).map(Self::Decimal)
}
}
impl<S, T, D> From<Vec<u8>> for GenericBareItem<S, Vec<u8>, T, D> {
fn from(val: Vec<u8>) -> Self {
Self::ByteSequence(val)
}
}
impl<S, B, D> From<Token> for GenericBareItem<S, B, Token, D> {
fn from(val: Token) -> Self {
Self::Token(val)
}
}
impl<B, T, D> From<String> for GenericBareItem<String, B, T, D> {
fn from(val: String) -> Self {
Self::String(val)
}
}
impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, Vec<u8>, T, D> {
fn from(val: &'a [u8]) -> Self {
Self::ByteSequence(val.to_owned())
}
}
impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, Token, D> {
fn from(val: &'a TokenRef) -> Self {
Self::Token(val.to_owned())
}
}
impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<String, B, T, D> {
fn from(val: &'a StringRef) -> Self {
Self::String(val.to_owned())
}
}
#[derive(Debug, PartialEq)]
pub(crate) enum Num {
Decimal(Decimal),
Integer(Integer),
}
#[cfg_attr(
feature = "parsed-types",
doc = "Used to construct an [`Item`] or [`Parameters`] values."
)]
pub type BareItem = GenericBareItem<String, Vec<u8>, Token, StdString>;
pub type RefBareItem<'a> = GenericBareItem<&'a StringRef, &'a [u8], &'a TokenRef, &'a str>;
pub type BareItemFromInput<'a> =
GenericBareItem<Cow<'a, StringRef>, Vec<u8>, &'a TokenRef, Cow<'a, str>>;
impl<'a, S, B, T, D> From<&'a GenericBareItem<S, B, T, D>> for RefBareItem<'a>
where
S: Borrow<StringRef>,
B: Borrow<[u8]>,
T: Borrow<TokenRef>,
D: Borrow<str>,
{
fn from(val: &'a GenericBareItem<S, B, T, D>) -> RefBareItem<'a> {
match val {
GenericBareItem::Integer(val) => RefBareItem::Integer(*val),
GenericBareItem::Decimal(val) => RefBareItem::Decimal(*val),
GenericBareItem::String(val) => RefBareItem::String(val.borrow()),
GenericBareItem::ByteSequence(val) => RefBareItem::ByteSequence(val.borrow()),
GenericBareItem::Boolean(val) => RefBareItem::Boolean(*val),
GenericBareItem::Token(val) => RefBareItem::Token(val.borrow()),
GenericBareItem::Date(val) => RefBareItem::Date(*val),
GenericBareItem::DisplayString(val) => RefBareItem::DisplayString(val.borrow()),
}
}
}
impl<'a> From<BareItemFromInput<'a>> for BareItem {
fn from(val: BareItemFromInput<'a>) -> BareItem {
match val {
BareItemFromInput::Integer(val) => BareItem::Integer(val),
BareItemFromInput::Decimal(val) => BareItem::Decimal(val),
BareItemFromInput::String(val) => BareItem::String(val.into_owned()),
BareItemFromInput::ByteSequence(val) => BareItem::ByteSequence(val),
BareItemFromInput::Boolean(val) => BareItem::Boolean(val),
BareItemFromInput::Token(val) => BareItem::Token(val.to_owned()),
BareItemFromInput::Date(val) => BareItem::Date(val),
BareItemFromInput::DisplayString(val) => BareItem::DisplayString(val.into_owned()),
}
}
}
impl<'a> From<RefBareItem<'a>> for BareItem {
fn from(val: RefBareItem<'a>) -> BareItem {
match val {
RefBareItem::Integer(val) => BareItem::Integer(val),
RefBareItem::Decimal(val) => BareItem::Decimal(val),
RefBareItem::String(val) => BareItem::String(val.to_owned()),
RefBareItem::ByteSequence(val) => BareItem::ByteSequence(val.to_owned()),
RefBareItem::Boolean(val) => BareItem::Boolean(val),
RefBareItem::Token(val) => BareItem::Token(val.to_owned()),
RefBareItem::Date(val) => BareItem::Date(val),
RefBareItem::DisplayString(val) => BareItem::DisplayString(val.to_owned()),
}
}
}
impl<'a, S, T, D> From<&'a [u8]> for GenericBareItem<S, &'a [u8], T, D> {
fn from(val: &'a [u8]) -> Self {
Self::ByteSequence(val)
}
}
impl<'a, S, B, D> From<&'a Token> for GenericBareItem<S, B, &'a TokenRef, D> {
fn from(val: &'a Token) -> Self {
Self::Token(val)
}
}
impl<'a, S, B, D> From<&'a TokenRef> for GenericBareItem<S, B, &'a TokenRef, D> {
fn from(val: &'a TokenRef) -> Self {
Self::Token(val)
}
}
impl<'a, B, T, D> From<&'a String> for GenericBareItem<&'a StringRef, B, T, D> {
fn from(val: &'a String) -> Self {
Self::String(val)
}
}
impl<'a, B, T, D> From<&'a StringRef> for GenericBareItem<&'a StringRef, B, T, D> {
fn from(val: &'a StringRef) -> Self {
Self::String(val)
}
}
impl<S1, B1, T1, D1, S2, B2, T2, D2> PartialEq<GenericBareItem<S2, B2, T2, D2>>
for GenericBareItem<S1, B1, T1, D1>
where
for<'a> RefBareItem<'a>: From<&'a Self>,
for<'a> RefBareItem<'a>: From<&'a GenericBareItem<S2, B2, T2, D2>>,
{
fn eq(&self, other: &GenericBareItem<S2, B2, T2, D2>) -> bool {
match (RefBareItem::from(self), RefBareItem::from(other)) {
(RefBareItem::Integer(a), RefBareItem::Integer(b)) => a == b,
(RefBareItem::Decimal(a), RefBareItem::Decimal(b)) => a == b,
(RefBareItem::String(a), RefBareItem::String(b)) => a == b,
(RefBareItem::ByteSequence(a), RefBareItem::ByteSequence(b)) => a == b,
(RefBareItem::Boolean(a), RefBareItem::Boolean(b)) => a == b,
(RefBareItem::Token(a), RefBareItem::Token(b)) => a == b,
(RefBareItem::Date(a), RefBareItem::Date(b)) => a == b,
(RefBareItem::DisplayString(a), RefBareItem::DisplayString(b)) => a == b,
_ => false,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Version {
Rfc8941,
Rfc9651,
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Self::Rfc8941 => "RFC 8941",
Self::Rfc9651 => "RFC 9651",
})
}
}
mod private {
#[allow(unused)]
pub trait Sealed {}
}