svd_encoder/
lib.rs

1//! Encode traits.
2//! These support encoding of SVD types to XML
3
4use svd_rs as svd;
5
6use crate::svd::Device;
7use xmltree::{Element, EmitterConfig, XMLNode};
8
9pub use crate::config::{
10    Config, DerivableSorting, IdentifierFormat, NumberFormat, RcSorting, Sorting,
11};
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
14pub enum EncodeError {}
15
16/// Encode trait allows SVD objects to be encoded into XML elements.
17pub trait Encode {
18    /// Encoding error
19    type Error;
20    /// Encode into an XML/SVD element
21    fn encode(&self) -> Result<Element, Self::Error> {
22        self.encode_with_config(&Config::default())
23    }
24    /// Encode into an XML/SVD element with a custom configuration
25    fn encode_with_config(&self, config: &Config) -> Result<Element, Self::Error>;
26    fn encode_node(&self) -> Result<XMLNode, Self::Error> {
27        self.encode().map(XMLNode::Element)
28    }
29    fn encode_node_with_config(&self, config: &Config) -> Result<XMLNode, Self::Error> {
30        self.encode_with_config(config).map(XMLNode::Element)
31    }
32}
33
34/// EncodeChildren allows SVD objects to be encoded as a list of XML nodes
35/// This is typically used to merge with an existing element.
36pub trait EncodeChildren {
37    /// Encoding error
38    type Error;
39    /// Encode into XML/SVD children to merge with existing object
40    fn encode(&self) -> Result<Vec<XMLNode>, Self::Error> {
41        self.encode_with_config(&Config::default())
42    }
43    /// Encode into XML/SVD children to merge with existing object with a custom configuration
44    fn encode_with_config(&self, config: &Config) -> Result<Vec<XMLNode>, Self::Error>;
45}
46
47/// Encodes a device object to an SVD (XML) string
48pub fn encode(d: &Device) -> Result<String, EncodeError> {
49    encode_with_config(d, &Config::default())
50}
51
52/// Encodes a device object to an SVD (XML) string
53pub fn encode_with_config(d: &Device, config: &Config) -> Result<String, EncodeError> {
54    let root = d.encode_with_config(config)?;
55    let mut wr = Vec::new();
56    let mut cfg = EmitterConfig::new();
57    cfg.perform_indent = true;
58    cfg.pad_self_closing = false;
59    root.write_with_config(&mut wr, cfg).unwrap();
60    Ok(String::from_utf8(wr).unwrap())
61}
62
63/// Defines extensions for implementation over xmltree::Element
64trait ElementMerge {
65    fn merge(&mut self, n: &Self);
66}
67/// Implements extensions for xmltree::Element
68impl ElementMerge for Element {
69    // Merges the children of two elements, maintaining the name and description of the first
70    fn merge(&mut self, r: &Self) {
71        self.children.extend(r.children.iter().cloned());
72        for (key, val) in &r.attributes {
73            self.attributes.insert(key.clone(), val.clone());
74        }
75    }
76}
77
78/// Helper to create new base xml nodes
79pub(crate) fn new_node(name: &str, text: String) -> XMLNode {
80    let mut e = Element::new(name);
81    e.children.push(XMLNode::Text(text));
82    XMLNode::Element(e)
83}
84
85mod access;
86mod addressblock;
87mod bitrange;
88mod cluster;
89mod config;
90mod cpu;
91mod datatype;
92mod device;
93mod dimelement;
94mod endian;
95mod enumeratedvalue;
96mod enumeratedvalues;
97mod field;
98mod interrupt;
99mod modifiedwritevalues;
100mod peripheral;
101mod protection;
102mod readaction;
103mod register;
104mod registercluster;
105mod registerproperties;
106mod usage;
107mod writeconstraint;