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
|
// elements resemble a final tree, including inherited namespace information
use std::collections::HashMap;
// when are namespaces names chosen then if they are automatically calculated
// namespaces are held by readers and writers.
pub struct Namespace {
prefix: Option<String>,
namespace: String,
}
// names are qualified, they contain a reference to the namespace (held within the reader/writer)
pub struct Name {
namespace: String,
name: String,
}
pub enum Node {
Element(Element),
Text(String),
}
// should this be a trait?
pub struct Element {
pub name: Name,
// namespace: Name,
// each element once created contains the qualified namespace information for that element
// the name contains the qualified namespace so this is unnecessary
// namespace: String,
// hashmap of explicit namespace declarations on the element itself only
// possibly not needed as can be calculated at write time depending on context and qualified namespace, and for reading, element validity and namespaces are kept track of by the reader.
pub namespace_decl: HashMap<Option<String>, String>,
// attributes can be in a different namespace than the element. how to make sure they are valid?
// maybe include the namespace instead of or with the prefix
// you can calculate the prefix from the namespaced name and the current writer context
// you can validate the prefix and calculate the namespace from the current reader context
// this results in readers and writers being able to return qualification errors as they aren't able to create elements until every part is qualified.
pub attributes: HashMap<Name, String>,
pub children: Option<Vec<Node>>,
}
// example of deriving an element:
// #[derive(XMLWrite, XMLRead)]
// #[peanuts(xmlns = "jabber:client", xmlns:stream = "http://etherx.jabber.org/streams", prefix = "stream")]
// pub struct Stream {
// from: JID,
// id: String,
// to: JID,
// version: String,
// #[peanuts(namespace = "http://www.w3.org/XML/1998/namespace")]
// lang: Lang,
// }
// note: if an element name has a prefix all unprefixed attributes are qualified by the namespace of the prefix, so in this example from's Name's namespace would be "http://etherx.jabber.org/streams"
|