use alloc::collections::BTreeMap; use alloc::vec; use core::fmt; use core::hash::Hash; use core::mem::discriminant; use core::ops; #[cfg(feature = "std")] use std::collections::HashMap;
use serde_core::de; use serde_core::de::IntoDeserializer; use serde_core::ser;
/// Type representing a TOML array, payload of the `Value::Array` variant pubtype Array = Vec<Value>;
#[doc(no_inline)] pubusecrate::Table;
/// Representation of a TOML value. #[derive(PartialEq, Clone, Debug)] pubenum Value { /// Represents a TOML string
String(String), /// Represents a TOML integer
Integer(i64), /// Represents a TOML float
Float(f64), /// Represents a TOML boolean
Boolean(bool), /// Represents a TOML datetime
Datetime(Datetime), /// Represents a TOML array
Array(Array), /// Represents a TOML table
Table(Table),
}
impl Value { /// Convert a `T` into `toml::Value` which is an enum that can represent /// any valid TOML data. /// /// This conversion can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. pubfn try_from<T>(value: T) -> Result<Self, crate::ser::Error> where
T: ser::Serialize,
{
value.serialize(ValueSerializer)
}
/// Interpret a `toml::Value` as an instance of type `T`. /// /// This conversion can fail if the structure of the `Value` does not match the /// structure expected by `T`, for example if `T` is a struct type but the /// `Value` contains something other than a TOML table. It can also fail if the /// structure is correct but `T`'s implementation of `Deserialize` decides that /// something is wrong with the data, for example required struct fields are /// missing from the TOML map or some number is too big to fit in the expected /// primitive type. pubfn try_into<'de, T>(self) -> Result<T, crate::de::Error> where
T: de::Deserialize<'de>,
{
de::Deserialize::deserialize(self)
}
/// Index into a TOML array or map. A string index can be used to access a /// value in a map, and a usize index can be used to access an element of an /// array. /// /// Returns `None` if the type of `self` does not match the type of the /// index, for example if the index is a string and `self` is an array or a /// number. Also returns `None` if the given key does not exist in the map /// or the given index is not within the bounds of the array. pubfn get<I: Index>(&self, index: I) -> Option<&Self> {
index.index(self)
}
/// Mutably index into a TOML array or map. A string index can be used to /// access a value in a map, and a usize index can be used to access an /// element of an array. /// /// Returns `None` if the type of `self` does not match the type of the /// index, for example if the index is a string and `self` is an array or a /// number. Also returns `None` if the given key does not exist in the map /// or the given index is not within the bounds of the array. pubfn get_mut<I: Index>(&mutself, index: I) -> Option<&mutSelf> {
index.index_mut(self)
}
/// Extracts the integer value if it is an integer. pubfn as_integer(&self) -> Option<i64> { match *self { Self::Integer(i) => Some(i),
_ => None,
}
}
/// Tests whether this value is an integer. pubfn is_integer(&self) -> bool { self.as_integer().is_some()
}
/// Extracts the float value if it is a float. pubfn as_float(&self) -> Option<f64> { match *self { Self::Float(f) => Some(f),
_ => None,
}
}
/// Tests whether this value is a float. pubfn is_float(&self) -> bool { self.as_float().is_some()
}
/// Extracts the boolean value if it is a boolean. pubfn as_bool(&self) -> Option<bool> { match *self { Self::Boolean(b) => Some(b),
_ => None,
}
}
/// Tests whether this value is a boolean. pubfn is_bool(&self) -> bool { self.as_bool().is_some()
}
/// Extracts the string of this value if it is a string. pubfn as_str(&self) -> Option<&str> { match *self { Self::String(ref s) => Some(&**s),
_ => None,
}
}
/// Tests if this value is a string. pubfn is_str(&self) -> bool { self.as_str().is_some()
}
/// Extracts the datetime value if it is a datetime. /// /// Note that a parsed TOML value will only contain ISO 8601 dates. An /// example date is: /// /// ```notrust /// 1979-05-27T07:32:00Z /// ``` pubfn as_datetime(&self) -> Option<&Datetime> { match *self { Self::Datetime(ref s) => Some(s),
_ => None,
}
}
/// Tests whether this value is a datetime. pubfn is_datetime(&self) -> bool { self.as_datetime().is_some()
}
/// Extracts the array value if it is an array. pubfn as_array(&self) -> Option<&Vec<Self>> { match *self { Self::Array(ref s) => Some(s),
_ => None,
}
}
/// Extracts the array value if it is an array. pubfn as_array_mut(&mutself) -> Option<&mut Vec<Self>> { match *self { Self::Array(refmut s) => Some(s),
_ => None,
}
}
/// Tests whether this value is an array. pubfn is_array(&self) -> bool { self.as_array().is_some()
}
/// Extracts the table value if it is a table. pubfn as_table(&self) -> Option<&Table> { match *self { Self::Table(ref s) => Some(s),
_ => None,
}
}
/// Extracts the table value if it is a table. pubfn as_table_mut(&mutself) -> Option<&mut Table> { match *self { Self::Table(refmut s) => Some(s),
_ => None,
}
}
/// Tests whether this value is a table. pubfn is_table(&self) -> bool { self.as_table().is_some()
}
/// Tests whether this and another value have the same type. pubfn same_type(&self, other: &Self) -> bool {
discriminant(self) == discriminant(other)
}
/// Returns a human-readable representation of the type of this value. pubfn type_str(&self) -> &'static str { match *self { Self::String(..) => "string", Self::Integer(..) => "integer", Self::Float(..) => "float", Self::Boolean(..) => "boolean", Self::Datetime(..) => "datetime", Self::Array(..) => "array", Self::Table(..) => "table",
}
}
}
impl<I> ops::Index<I> for Value where
I: Index,
{ type Output = Self;
/// Types that can be used to index a `toml::Value` /// /// Currently this is implemented for `usize` to index arrays and `str` to index /// tables. /// /// This trait is sealed and not intended for implementation outside of the /// `toml` crate. pubtrait Index: Sealed { #[doc(hidden)] fn index<'a>(&self, val: &'a Value) -> Option<&'a Value>; #[doc(hidden)] fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value>;
}
/// An implementation detail that should not be implemented, this will change in /// the future and break code otherwise. #[doc(hidden)] pubtrait Sealed {} impl Sealed for usize {} impl Sealed for str {} impl Sealed for String {} impl<T: Sealed + ?Sized> Sealed for &T {}
impl Index for usize { fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> { match *val {
Value::Array(ref a) => a.get(*self),
_ => None,
}
}
fn visit_u64<E: de::Error>(self, value: u64) -> Result<Value, E> { if i64::try_from(value).is_ok() {
Ok(Value::Integer(value as i64))
} else {
Err(de::Error::custom("u64 value was too large"))
}
}
// This is wrapped by `Table` and any trait methods implemented here need to be wrapped there. impl<'de> de::Deserializer<'de> for Value { type Error = crate::de::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> where
V: de::Visitor<'de>,
{ matchself { Self::Boolean(v) => visitor.visit_bool(v), Self::Integer(n) => visitor.visit_i64(n), Self::Float(n) => visitor.visit_f64(n), Self::String(v) => visitor.visit_string(v), Self::Datetime(v) => visitor.visit_string(v.to_string()), Self::Array(v) => { let len = v.len(); letmut deserializer = SeqDeserializer::new(v); let seq = visitor.visit_seq(&mut deserializer)?; let remaining = deserializer.iter.len(); if remaining == 0 {
Ok(seq)
} else {
Err(de::Error::invalid_length(len, &"fewer elements in array"))
}
} Self::Table(v) => { let len = v.len(); letmut deserializer = MapDeserializer::new(v); let map = visitor.visit_map(&mut deserializer)?; let remaining = deserializer.iter.len(); if remaining == 0 {
Ok(map)
} else {
Err(de::Error::invalid_length(len, &"fewer elements in map"))
}
}
}
}
// `None` is interpreted as a missing field so be sure to implement `Some` // as a present field. fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> where
V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> where
V: de::Visitor<'de>,
{ use de::Error; matchself.value {
Value::Array(values) => { if values.len() == len {
de::Deserializer::deserialize_seq(values.into_deserializer(), visitor)
} else {
Err(Error::custom(format!("expected tuple with length {len}")))
}
}
Value::Table(values) => { let tuple_values: Result<Vec<_>, _> = values
.into_iter()
.enumerate()
.map(|(index, (key, value))| match key.parse::<usize>() {
Ok(key_index) if key_index == index => Ok(value),
Ok(_) | Err(_) => Err(Error::custom(format!( "expected table key `{index}`, but was `{key}`"
))),
})
.collect(); let tuple_values = tuple_values?;
if tuple_values.len() == len {
de::Deserializer::deserialize_seq(tuple_values.into_deserializer(), visitor)
} else {
Err(Error::custom(format!("expected tuple with length {len}")))
}
}
e => Err(Error::custom(format!( "expected table, found {}",
e.type_str()
))),
}
}
fn struct_variant<V>( self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> where
V: de::Visitor<'de>,
{
de::Deserializer::deserialize_struct( self.value.into_deserializer(), "", // TODO: this should be the variant name
fields,
visitor,
)
}
}
impl IntoDeserializer<'_, crate::de::Error> for Value { type Deserializer = Self;
fn into_deserializer(self) -> Self { self
}
}
pub(crate) struct ValueSerializer;
impl ser::Serializer for ValueSerializer { type Ok = Value; type Error = crate::ser::Error;
type SerializeSeq = ValueSerializeVec; type SerializeTuple = ValueSerializeVec; type SerializeTupleStruct = ValueSerializeVec; type SerializeTupleVariant = ValueSerializeTupleVariant; type SerializeMap = ValueSerializeMap; type SerializeStruct = ValueSerializeMap; type SerializeStructVariant = ValueSerializeStructVariant;
fn serialize_u64(self, value: u64) -> Result<Value, crate::ser::Error> { if i64::try_from(value).is_ok() { self.serialize_i64(value as i64)
} else {
Err(ser::Error::custom("u64 value was too large"))
}
}
type ValueSerializeTupleVariant = ValueSerializeVariant<ValueSerializeVec>; type ValueSerializeStructVariant = ValueSerializeVariant<ValueSerializeMap>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.