1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
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);
// 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_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)]
DeserializeFailed(#[from] DeserializerError<Infallible>),
}
impl_from_deserializer_error!(FavoritesError);
|