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;