use std::collections::{BTreeMap, HashMap}; use std::fmt; use std::hash::Hash; use std::mem::discriminant; use std::ops; use std::str::FromStr; use std::vec;
use serde::de; use serde::de::IntoDeserializer; use serde::ser;
/// 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),
}
/// Type representing a TOML array, payload of the `Value::Array` variant pubtype Array = Vec<Value>;
/// Type representing a TOML table, payload of the `Value::Table` variant. /// By default it is backed by a BTreeMap, enable the `preserve_order` feature /// to use a LinkedHashMap instead. pubtype Table = Map<String, Value>;
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<Value, crate::ser::Error> where
T: ser::Serialize,
{
value.serialize(Serializer)
}
/// 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<&Value> {
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<&mut Value> {
index.index_mut(self)
}
/// Extracts the integer value if it is an integer. pubfn as_integer(&self) -> Option<i64> { match *self {
Value::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 {
Value::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 {
Value::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 {
Value::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 {
Value::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<Value>> { match *self {
Value::Array(ref s) => Some(s),
_ => None,
}
}
/// Extracts the array value if it is an array. pubfn as_array_mut(&mutself) -> Option<&mut Vec<Value>> { match *self {
Value::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 {
Value::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 {
Value::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: &Value) -> bool {
discriminant(self) == discriminant(other)
}
/// Returns a human-readable representation of the type of this value. pubfn type_str(&self) -> &'static str { match *self {
Value::String(..) => "string",
Value::Integer(..) => "integer",
Value::Float(..) => "float",
Value::Boolean(..) => "boolean",
Value::Datetime(..) => "datetime",
Value::Array(..) => "array",
Value::Table(..) => "table",
}
}
}
impl<I> ops::Index<I> for Value where
I: Index,
{ type Output = Value;
impl<I> ops::IndexMut<I> for Value where
I: Index,
{ fn index_mut(&mutself, index: I) -> &mut Value { self.get_mut(index).expect("index not found")
}
}
impl<'a> From<&'a str> for Value { #[inline] fn from(val: &'a str) -> Value {
Value::String(val.to_string())
}
}
impl<V: Into<Value>> From<Vec<V>> for Value { fn from(val: Vec<V>) -> Value {
Value::Array(val.into_iter().map(|v| v.into()).collect())
}
}
impl<S: Into<String>, V: Into<Value>> From<BTreeMap<S, V>> for Value { fn from(val: BTreeMap<S, V>) -> Value { let table = val.into_iter().map(|(s, v)| (s.into(), v.into())).collect();
Value::Table(table)
}
}
impl<S: Into<String> + Hash + Eq, V: Into<Value>> From<HashMap<S, V>> for Value { fn from(val: HashMap<S, V>) -> Value { let table = val.into_iter().map(|(s, v)| (s.into(), v.into())).collect();
Value::Table(table)
}
}
macro_rules! impl_into_value {
($variant:ident : $T:ty) => { impl From<$T> for Value { #[inline] fn from(val: $T) -> Value {
Value::$variant(val.into())
}
}
};
}
/// 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<'a, T: Sealed + ?Sized> Sealed for &'a 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,
}
}
impl fmt::Display for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { crate::ser::to_string(self)
.expect("Unable to represent value as string")
.fmt(f)
}
}
impl FromStr for Value { type Err = crate::de::Error; fn from_str(s: &str) -> Result<Value, Self::Err> { crate::from_str(s)
}
}
impl ser::Serialize for Value { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
S: ser::Serializer,
{ use serde::ser::SerializeMap;
match *self {
Value::String(ref s) => serializer.serialize_str(s),
Value::Integer(i) => serializer.serialize_i64(i),
Value::Float(f) => serializer.serialize_f64(f),
Value::Boolean(b) => serializer.serialize_bool(b),
Value::Datetime(ref s) => s.serialize(serializer),
Value::Array(ref a) => a.serialize(serializer),
Value::Table(ref t) => { letmut map = serializer.serialize_map(Some(t.len()))?; // Be sure to visit non-tables first (and also non // array-of-tables) as all keys must be emitted first. for (k, v) in t { if !v.is_table() && !v.is_array()
|| (v
.as_array()
.map(|a| !a.iter().any(|v| v.is_table()))
.unwrap_or(false))
{
map.serialize_entry(k, v)?;
}
} for (k, v) in t { if v.as_array()
.map(|a| a.iter().any(|v| v.is_table()))
.unwrap_or(false)
{
map.serialize_entry(k, v)?;
}
} for (k, v) in t { if v.is_table() {
map.serialize_entry(k, v)?;
}
}
map.end()
}
}
}
}
impl<'de> de::Deserialize<'de> for Value { fn deserialize<D>(deserializer: D) -> Result<Value, D::Error> where
D: de::Deserializer<'de>,
{ struct ValueVisitor;
impl<'de> de::Visitor<'de> for ValueVisitor { type Value = Value;
fn visit_u64<E: de::Error>(self, value: u64) -> Result<Value, E> { if value <= i64::max_value() as u64 {
Ok(Value::Integer(value as i64))
} else {
Err(de::Error::custom("u64 value was too large"))
}
}
// `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)
}
impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value { type Deserializer = Self;
fn into_deserializer(self) -> Self { self
}
}
struct Serializer;
impl ser::Serializer for Serializer { type Ok = Value; type Error = crate::ser::Error;
type SerializeSeq = SerializeVec; type SerializeTuple = SerializeVec; type SerializeTupleStruct = SerializeVec; type SerializeTupleVariant = SerializeVec; type SerializeMap = SerializeMap; type SerializeStruct = SerializeMap; type SerializeStructVariant = ser::Impossible<Value, crate::ser::Error>;
fn serialize_u64(self, value: u64) -> Result<Value, crate::ser::Error> { if value <= i64::max_value() as u64 { self.serialize_i64(value as i64)
} else {
Err(ser::Error::custom("u64 value was too large"))
}
}
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.