//! Path-based metadata to serialize with a value. //! //! Path-based in this context means that the metadata is linked //! to the data in a relative and hierarchical fashion by tracking //! the current absolute path of the field being serialized. //! //! # Example //! //! ``` //! # use ron::ser::{PrettyConfig, path_meta::Field}; //! //! #[derive(serde::Serialize)] //! struct Creature { //! seconds_since_existing: usize, //! linked: Option<Box<Self>>, //! } //! //! let mut config = PrettyConfig::default(); //! //! config //! .path_meta //! // The path meta defaults to no root structure, //! // so we either provide a prebuilt one or initialize //! // an empty one to build. //! .get_or_insert_with(Field::empty) //! .build_fields(|fields| { //! fields //! // Get or insert the named field //! .field("seconds_since_existing") //! .with_doc("Outer seconds_since_existing"); //! fields //! .field("linked") //! // Doc metadata is serialized preceded by three forward slashes and a space for each line //! .with_doc("Optional.\nProvide another creature to be wrapped.") //! // Even though it's another Creature, the fields have different paths, so they are addressed separately. //! .build_fields(|fields| { //! fields //! .field("seconds_since_existing") //! .with_doc("Inner seconds_since_existing"); //! }); //! }); //! //! let value = Creature { //! seconds_since_existing: 0, //! linked: Some(Box::new(Creature { //! seconds_since_existing: 0, //! linked: None, //! })), //! }; //! //! let s = ron::ser::to_string_pretty(&value, config).unwrap(); //! //! assert_eq!(s, r#"( //! /// Outer seconds_since_existing //! seconds_since_existing: 0, //! /// Optional. //! /// Provide another creature to be wrapped. //! linked: Some(( //! /// Inner seconds_since_existing //! seconds_since_existing: 0, //! linked: None, //! )), //! )"#); //! ``` //! //! # Identical paths //! //! Especially in enums and tuples it's possible for fields //! to share a path, thus being unable to be addressed separately. //! //! ```no_run //! enum Kind { //! A { //! field: (), //! }, // ^ //! // cannot be addressed separately because they have the same path //! B { // v //! field: (), //! }, //! } //! ``` //! //! ```no_run //! struct A { //! field: (), //! } //! //! struct B { //! field: (), //! } //! //! type Value = ( //! A, //! // ^ //! // These are different types, but they share the path `field` //! // v //! B, //! ); //! ```
use alloc::string::String;
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "std")] use std::collections::HashMap as FieldsInner;
#[cfg(not(feature = "std"))] use alloc::collections::BTreeMap as FieldsInner;
/// The metadata and inner [`Fields`] of a field. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] pubstruct Field {
doc: String,
fields: Option<Fields>,
}
impl Field { /// Create a new empty field metadata. #[must_use] pubconstfn empty() -> Self { Self {
doc: String::new(),
fields: None,
}
}
/// Create a new field metadata from parts. pubfn new(doc: impl Into<String>, fields: Option<Fields>) -> Self { Self {
doc: doc.into(),
fields,
}
}
/// Get a shared reference to the documentation metadata of this field. #[inline] #[must_use] pubfn doc(&self) -> &str { self.doc.as_str()
}
/// Get a mutable reference to the documentation metadata of this field. #[inline] #[must_use] pubfn doc_mut(&mutself) -> &mut String {
&mutself.doc
}
/// Set the documentation metadata of this field. /// /// ``` /// # use ron::ser::path_meta::Field; /// /// let mut field = Field::empty(); /// /// assert_eq!(field.doc(), ""); /// /// field.with_doc("some meta"); /// /// assert_eq!(field.doc(), "some meta"); /// ``` pubfn with_doc(&mutself, doc: impl Into<String>) -> &mutSelf { self.doc = doc.into(); self
}
/// Get a shared reference to the inner fields of this field, if it has any. #[must_use] pubfn fields(&self) -> Option<&Fields> { self.fields.as_ref()
}
/// Get a mutable reference to the inner fields of this field, if it has any. pubfn fields_mut(&mutself) -> Option<&mutFields> { self.fields.as_mut()
}
/// Return whether this field has inner fields. /// /// ``` /// # use ron::ser::path_meta::{Field, Fields}; /// /// let mut field = Field::empty(); /// /// assert!(!field.has_fields()); /// /// field.with_fields(Some(Fields::default())); /// /// assert!(field.has_fields()); /// ``` #[must_use] pubfn has_fields(&self) -> bool { self.fields.is_some()
}
/// Set the inner fields of this field. /// /// ``` /// # use ron::ser::path_meta::{Field, Fields}; /// /// let mut field = Field::empty(); /// /// assert!(!field.has_fields()); /// /// field.with_fields(Some(Fields::default())); /// /// assert!(field.has_fields()); /// /// field.with_fields(None); /// /// assert!(!field.has_fields()); /// ``` pubfn with_fields(&mutself, fields: Option<Fields>) -> &'color:red'>mutSelf { self.fields = fields; self
}
/// Ergonomic shortcut for building some inner fields. /// /// ``` /// # use ron::ser::path_meta::Field; /// /// let mut field = Field::empty(); /// /// field.build_fields(|fields| { /// fields.field("inner field"); /// }); /// /// assert_eq!(field.fields().map(|fields| fields.contains("inner field")), Some(true)); /// ``` pubfn build_fields(&mutself, builder: impl FnOnce(&mut Fields)) -> &mutSelf { letmut fields = Fields::default();
builder(&mut fields); self.with_fields(Some(fields)); self
}
}
/// Mapping of names to [`Field`]s. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] pubstruct Fields {
fields: FieldsInner<String, Field>,
}
impl Fields { /// Return a new, empty metadata field map. #[must_use] pubfn new() -> Self { Self::default()
}
/// Return whether this field map contains no fields. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let mut fields = Fields::default(); /// /// assert!(fields.is_empty()); /// /// fields.insert("", Field::empty()); /// /// assert!(!fields.is_empty()); /// ``` #[must_use] pubfn is_empty(&self) -> bool { self.fields.is_empty()
}
/// Return whether this field map contains a field with the given name. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let fields: Fields = [("a thing", Field::empty())].into_iter().collect(); /// /// assert!(fields.contains("a thing")); /// assert!(!fields.contains("not a thing")); /// ``` pubfn contains(&self, name: impl AsRef<str>) -> bool { self.fields.contains_key(name.as_ref())
}
/// Get a reference to the field with the provided `name`, if it exists. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let fields: Fields = [("a thing", Field::empty())].into_iter().collect(); /// /// assert!(fields.get("a thing").is_some()); /// assert!(fields.get("not a thing").is_none()); /// ``` pubfn get(&self, name: impl AsRef<str>) -> Option<&Field> { self.fields.get(name.as_ref())
}
/// Get a mutable reference to the field with the provided `name`, if it exists. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let mut fields: Fields = [("a thing", Field::empty())].into_iter().collect(); /// /// assert!(fields.get_mut("a thing").is_some()); /// assert!(fields.get_mut("not a thing").is_none()); /// ``` pubfn get_mut(&mutself, name: impl AsRef<str>) -> Option<&'color:red'>mut Field> { self.fields.get_mut(name.as_ref())
}
/// Insert a field with the given name into the map. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let mut fields = Fields::default(); /// /// assert!(fields.insert("field", Field::empty()).is_none()); /// assert!(fields.insert("field", Field::empty()).is_some()); /// ``` pubfn insert(&mutself, name: impl Into<String>, field: Field) -> Option<Field> { self.fields.insert(name.into(), field)
}
/// Remove a field with the given name from the map. /// /// ``` /// # use ron::ser::path_meta::{Fields, Field}; /// /// let mut fields: Fields = [("a", Field::empty())].into_iter().collect(); /// /// assert_eq!(fields.remove("a"), Some(Field::empty())); /// assert_eq!(fields.remove("a"), None); /// ``` pubfn remove(&mutself, name: impl AsRef<str>) -> Option<Field> { self.fields.remove(name.as_ref())
}
/// Get a mutable reference to the field with the provided `name`, /// inserting an empty [`Field`] if it didn't exist. /// /// ``` /// # use ron::ser::path_meta::Fields; /// /// let mut fields = Fields::default(); /// /// assert!(!fields.contains("thing")); /// /// fields.field("thing"); /// /// assert!(fields.contains("thing")); /// ``` pubfn field(&mutself, name: impl Into<String>) -> &mut Field { self.fields.entry(name.into()).or_insert_with(Field::empty)
}
}
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.