diet_xml/lib.rs
1//! # diet-xml
2//!
3//! A schema-driven, ergonomic XML builder for Rust.
4//!
5
6//! ## Example
7//! ```rust
8//! use diet_xml::XmlBuilder;
9//!
10//! fn main() {
11//!
12//! // example data
13//! let employees = vec![
14//! Employee { id: 1, first: "John", last: "Doe", dob: "1900-01-01" },
15//! Employee { id: 2, first: "Jane", last: "Doe", dob: "1800-12-31" },
16//! Employee { id: 3, first: "John", last: "Dough", dob: "1700-01-01" },
17//! ];
18//!
19//! // create an XmlBuilder struct
20//!
21//! // this is a struct that allows you build an xml output in memory
22//! let mut xb = XmlBuilder::new();
23//!
24//! // define the schema you wish to populate in plain text
25//! xb.set_schema("
26//! <root>
27//! <employee>
28//! <name>
29//! <first></first>
30//! <last></last>
31//! </name>
32//! <info>
33//! <dob></dob>
34//! </info>
35//! </employee>
36//! <passing_str_ok></passing_str_ok>
37//! <passing_i32_ok></passing_i32_ok>
38//! <name!2></name!2>
39//! </root>");
40//!
41//! // default header is <?xml version="1.0" encoding="UTF-8"?>
42//! // to remove all headers use xb.clear_header();
43//! // to set customer header use xb.set_header("your customer header, < > will be applied the the star/end automatically");
44//!
45//! for e in employees{
46//!
47//! // we want each id to relate to it's own employee element
48//! // so use the id as the key
49//! // we can also chain into attributes to have the id display as an element attribute
50//!
51//! // these arguments can be anything that implments .to_string()
52//! // eg String, usize, &str, int
53//! // (element_the_key_is_on, key_value)
54//! // this is to allow the other to quickly add values to elements
55//! // without needing boiler plate to convert to text where possible
56//!
57//! xb.set_key("employee", e.id)
58//! .attribute("id", e.id);
59//!
60//! // you can chain either an add_element or set_key into .attribute
61//! // this takes two arguments
62//! // these arguments can be anything that implments .to_string()
63//! // eg String, usize, &str, int
64//! // (attribute_name, attribute_value)
65//! // the .attributes() method can be used to add multiple attributes
66//! // this should be passed in the form
67//! // &[(&str,&str),(&str,&str),(&str,&str),(&str,&str)]
68//! // tuples pairs of &str with attribute name and value
69//! // attribute and attributes can be chained from add_element also
70//!
71//! // now we simply add the element values we want populated
72//! // there is no need to build the entire structure
73//! // unlike other libraries the parent elements are implicitly built
74//! xb.add_element("first", e.first);
75//! xb.add_element("last", e.last);
76//!
77//! // you can chain into the cdata() method to enclose an element in cdata tags
78//! xb.add_element("dob", e.dob).cdata();
79//!
80//! // clears keys resets all context to a default value
81//! // this isn't necessary in this sample program
82//! // as keys are all overwritten on each iteration
83//! // keys retain their state until either overwritten or cleared
84//! xb.clear_keys();
85//! }
86//!
87//!
88//! // passing any type that implements to_string as a value for
89//! // add_element, attribute(), set_key is ok
90//! xb.add_element("passing_str_ok", "some str");
91//! xb.add_element("passing_i32_ok", 111222333);
92//!
93//! // duplicate element names should be distinguised by !AnyAlphaNumtext in the schema definition
94//! // the suffix will be remove when the XML is produced
95//! xb.add_element("name!2", "suffix !2 has been removed, this enables use of duplicate element names");
96//!
97//! // builds the xml in the background
98//! xb.build_xml();
99//!
100//!
101//! // function .xml_out() returns string of the xml output
102//! println!("{}", xb.xml_out());
103//! }
104//!
105//! struct Employee {
106//! id: usize,
107//! first: &'static str,
108//! last: &'static str,
109//! dob: &'static str,
110//! }
111//! ```
112
113mod builder;
114mod schema;
115
116// Public facing API
117pub struct XmlBuilder {
118 builder: builder::Builder,
119}
120
121impl XmlBuilder {
122 /// Overwrite the XML header (e.g., with a custom processing instruction)
123 pub fn set_header(&mut self, header: &str) {
124 self.builder.custom_header(header);
125 }
126
127 /// Clear all XML headers
128 pub fn clear_header(&mut self) {
129 self.builder.clear_headers();
130 }
131 pub fn new() -> Self {
132 XmlBuilder {
133 builder: builder::Builder::new(),
134 }
135 }
136
137 pub fn set_schema(&mut self, txt_schema: &str) {
138 self.builder.set_schema(txt_schema);
139 }
140
141 pub fn set_key<K: ToString>(&mut self, nm_element: &str, txt_key: K) -> ChainFromAdd {
142 let key_string = txt_key.to_string();
143 self.builder.set_key(nm_element, &key_string)
144 }
145
146 pub fn clear_keys(&mut self) {
147 self.builder.clear_key()
148 }
149
150 pub fn add_element<V: ToString>(&mut self, nm_element: &str, value_element: V) -> ChainFromAdd {
151 let value_string = value_element.to_string();
152 self.builder.add_element(nm_element, &value_string)
153 }
154
155 pub fn build_xml(&mut self) {
156 self.builder.build_xml();
157 }
158
159 pub fn xml_out(&self) -> &str {
160 &self.builder.xml_output
161 }
162
163
164 pub fn attributes(&mut self, attributes: &[(&str, &str)]) {
165
166 self.attributes(attributes);
167 }
168
169}
170
171// Re-export ChainFromAdd so users can call .attributes()
172pub use builder::ChainFromAdd;