aboutsummaryrefslogtreecommitdiff
path: root/examples/simple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/simple.rs')
-rw-r--r--examples/simple.rs143
1 files changed, 143 insertions, 0 deletions
diff --git a/examples/simple.rs b/examples/simple.rs
new file mode 100644
index 0000000..a4b76f2
--- /dev/null
+++ b/examples/simple.rs
@@ -0,0 +1,143 @@
+use std::convert::Infallible;
+use std::error::Error;
+use std::fmt::Debug;
+use std::fs::File;
+use std::io::BufReader;
+use std::path::Path;
+
+use xml_stinks::deserializer::buffered::Buffered as BufferedDeserializer;
+use xml_stinks::deserializer::{Deserializer, Error as DeserializerError, IgnoreEnd};
+use xml_stinks::tagged::TagStart;
+use xml_stinks::DeserializeTagged;
+
+const MANIFEST_DIR: &str = std::env!("CARGO_MANIFEST_DIR");
+
+fn main() -> Result<(), Box<dyn Error>>
+{
+ let data_file = Path::new(MANIFEST_DIR).join("examples/data.xml");
+
+ let reader = BufReader::new(File::open(data_file)?);
+
+ let mut deserializer = BufferedDeserializer::new(reader);
+
+ // Skip the <?xml version="1.0" encoding="UTF-8"?>
+ deserializer.skip_to_tag_start("data")?;
+
+ let data = deserializer.de_tag::<Data>("data", IgnoreEnd::No)?;
+
+ println!("The following data was deserialized:\n");
+
+ println!("Greeting: {}", data.greeting);
+ println!("Something: {}", data.something);
+ println!("Favorite food: {}", data.favorites.food);
+ println!("Favorite color: {}", data.favorites.color);
+
+ Ok(())
+}
+
+#[derive(Debug)]
+struct Data
+{
+ greeting: String,
+ something: String,
+ favorites: Favorites,
+}
+
+impl DeserializeTagged for Data
+{
+ type Error = DataError;
+
+ fn deserialize<TDeserializer: Deserializer>(
+ _start: &TagStart,
+ deserializer: &mut TDeserializer,
+ ) -> Result<Self, Self::Error>
+ {
+ let greeting_a = deserializer.de_text()?;
+
+ let something =
+ deserializer.de_tag_with("something", IgnoreEnd::No, |_, deserializer| {
+ deserializer.de_text()
+ })?;
+
+ let greeting_b = deserializer.de_text()?;
+
+ let favorites = deserializer.de_tag::<Favorites>("favorites", IgnoreEnd::No)?;
+
+ Ok(Self {
+ greeting: format!("{greeting_a} {greeting_b}"),
+ something,
+ favorites,
+ })
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+enum DataError
+{
+ #[error("Invalid favorites")]
+ InvalidFavorites(#[from] FavoritesError),
+
+ #[error(transparent)]
+ DeserializeFailed(#[from] DeserializerError<Infallible>),
+}
+
+impl<DeError: Into<Self>> From<DeserializerError<DeError>> for DataError
+{
+ fn from(err: DeserializerError<DeError>) -> Self
+ {
+ if let DeserializerError::DeserializeFailed(de_err) = err {
+ return de_err.into();
+ }
+
+ err.into_never_de_err().into()
+ }
+}
+
+#[derive(Debug)]
+struct Favorites
+{
+ food: String,
+ color: String,
+}
+
+impl DeserializeTagged for Favorites
+{
+ type Error = FavoritesError;
+
+ fn deserialize<TDeserializer: Deserializer>(
+ _start: &TagStart,
+ deserializer: &mut TDeserializer,
+ ) -> Result<Self, Self::Error>
+ {
+ let food =
+ deserializer.de_tag_with("food", IgnoreEnd::No, |_, deserializer| {
+ deserializer.de_text()
+ })?;
+
+ let color =
+ deserializer.de_tag_with("color", IgnoreEnd::No, |_, deserializer| {
+ deserializer.de_text()
+ })?;
+
+ Ok(Self { food, color })
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+enum FavoritesError
+{
+ #[error(transparent)]
+ DeserializeFailed(#[from] DeserializerError<Infallible>),
+}
+
+impl<DeError: Into<Self>> From<DeserializerError<DeError>> for FavoritesError
+{
+ fn from(err: DeserializerError<DeError>) -> Self
+ {
+ if let DeserializerError::DeserializeFailed(de_err) = err {
+ return de_err.into();
+ }
+
+ err.into_never_de_err().into()
+ }
+}