/// An encoding of a plist as a flat structure. /// /// Output by the event readers. /// /// Dictionary keys and values are represented as pairs of values e.g.: /// /// ```ignore rust /// StartDictionary /// String("Height") // Key /// Real(181.2) // Value /// String("Age") // Key /// Integer(28) // Value /// EndDictionary /// ``` /// /// ## Lifetimes /// /// This type has a lifetime parameter; during serialization, data is borrowed /// from a [`Value`], and the lifetime of the event is the lifetime of the /// [`Value`] being serialized. /// /// During deserialization, data is always copied anyway, and this lifetime /// is always `'static`. #[derive(Clone, Debug, PartialEq)] #[non_exhaustive] pubenum Event<'a> { // While the length of an array or dict cannot be feasably greater than max(usize) this better // conveys the concept of an effectively unbounded event stream.
StartArray(Option<u64>),
StartDictionary(Option<u64>),
EndCollection,
/// An owned [`Event`]. /// /// During deserialization, events are always owned; this type alias helps /// keep that code a bit clearer. pubtype OwnedEvent = Event<'static>;
/// An `Event` stream returned by `Value::into_events`. pubstruct Events<'a> {
stack: Vec<StackItem<'a>>,
}
/// Options for customizing serialization of XML plists. #[derive(Clone, Debug)] pubstruct XmlWriteOptions {
indent_str: Cow<'static, str>,
}
impl XmlWriteOptions { /// Specify the sequence of characters used for indentation. /// /// This may be either an `&'static str` or an owned `String`. /// /// The default is `\t`. pubfn indent_string(mutself, indent_str: impl Into<Cow<'static, str>>) -> Self { self.indent_str = indent_str.into(); self
}
}
impl<'a> Iterator for Events<'a> { type Item = Event<'a>;
fn next(&mutself) -> Option<Event<'a>> { fn handle_value<'c, 'b: 'c>(
value: &'b Value,
stack: &'c mut Vec<StackItem<'b>>,
) -> Event<'b> { match value {
Value::Array(array) => { let len = array.len(); let iter = array.iter();
stack.push(StackItem::Array(iter));
Event::StartArray(Some(len as u64))
}
Value::Dictionary(dict) => { let len = dict.len(); let iter = dict.into_iter();
stack.push(StackItem::Dict(iter));
Event::StartDictionary(Some(len as u64))
}
Value::Boolean(value) => Event::Boolean(*value),
Value::Data(value) => Event::Data(Cow::Borrowed(&value)),
Value::Date(value) => Event::Date(*value),
Value::Real(value) => Event::Real(*value),
Value::Integer(value) => Event::Integer(*value),
Value::String(value) => Event::String(Cow::Borrowed(value.as_str())),
Value::Uid(value) => Event::Uid(*value),
}
}
Some(matchself.stack.pop()? {
StackItem::Root(value) => handle_value(value, &mutself.stack),
StackItem::Array(mut array) => { iflet Some(value) = array.next() { // There might still be more items in the array so return it to the stack. self.stack.push(StackItem::Array(array));
handle_value(value, &mutself.stack)
} else {
Event::EndCollection
}
}
StackItem::Dict(mut dict) => { iflet Some((key, value)) = dict.next() { // There might still be more items in the dictionary so return it to the stack. self.stack.push(StackItem::Dict(dict)); // The next event to be returned must be the dictionary value. self.stack.push(StackItem::DictValue(value)); // Return the key event now.
Event::String(Cow::Borrowed(key))
} else {
Event::EndCollection
}
}
StackItem::DictValue(value) => handle_value(value, &mutself.stack),
})
}
}
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.