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::{impl_from_deserializer_error, 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);
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)]
DeserializerFailed(#[from] DeserializerError<Infallible>),
}
impl_from_deserializer_error!(DataError);
#[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)]
DeserializerFailed(#[from] DeserializerError<Infallible>),
}
impl_from_deserializer_error!(FavoritesError);