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 124 125 126 127 128 129 130 131 132
//! Serializing `indextree` structure. //! //! ## Version support //! //! | `indextree` version | `serde_indextree` version | //! |---------------------|---------------------------| //! | 3.3.x | 0.1.x | //! | 4.0.x | 0.2.x | //! //! ## Usage //! //! `serde_indextree` provides two struct: `Node` for serializing //! a node and its descendants, `SiblingNodes` for serializing a //! node and its siblings in sequence. //! //! ```rust //! use indextree::Arena; //! use serde::Serialize; //! use serde_indextree::Node; //! use serde_json::to_string_pretty; //! //! #[derive(Serialize)] //! struct HtmlElement { //! tag: &'static str //! } //! //! // <html> //! // <head> //! // <title></title> //! // <head> //! // <body> //! // <h1></h1> //! // <h2></h2> //! // </body> //! // </html> //! let arena = &mut Arena::new(); //! let a = arena.new_node(HtmlElement { tag: "html" }); //! let b = arena.new_node(HtmlElement { tag: "head" }); //! a.append(b, arena); //! let c = arena.new_node(HtmlElement { tag: "title" }); //! b.append(c, arena); //! let d = arena.new_node(HtmlElement { tag: "body" }); //! a.append(d, arena); //! let e = arena.new_node(HtmlElement { tag: "h1" }); //! d.append(e, arena); //! let f = arena.new_node(HtmlElement { tag: "h2" }); //! d.append(f, arena); //! //! println!("{}", to_string_pretty(&Node::new(a, arena)).unwrap()); //! // { //! // "tag": "html", //! // "children": [ //! // { //! // "tag": "head", //! // "children": [ //! // { //! // "tag": "title" //! // } //! // ] //! // }, //! // { //! // "tag": "body", //! // "children": [ //! // { //! // "tag": "h1" //! // }, //! // { //! // "tag": "h2" //! // } //! // ] //! // } //! // ] //! // } //! ``` //! //! ## Customization //! //! Unfortunately, `serde_indextree` doesn't come up with any customization. //! //! If you want to rename field names or anything, just copy the entire code //! (only 40+ lines) and modify it at your wish. //! //! ## License //! //! MIT use indextree::{Arena, NodeId}; use serde::ser::{SerializeSeq, Serializer}; use serde::Serialize; /// Convenience wrapper struct for serializing a node and its descendants. #[derive(Serialize)] pub struct Node<'a, T: Serialize> { #[serde(flatten)] data: &'a T, #[serde(skip_serializing_if = "Option::is_none")] children: Option<SiblingNodes<'a, T>>, } impl<'a, T: Serialize> Node<'a, T> { pub fn new(id: NodeId, arena: &'a Arena<T>) -> Self { let node = &arena[id]; Node { data: &node.get(), children: node .first_child() .map(|first| SiblingNodes::new(first, arena)), } } } /// Convenience wrapper struct for serializing a node and its siblings. pub struct SiblingNodes<'a, T: Serialize> { first: NodeId, arena: &'a Arena<T>, } impl<'a, T: Serialize> SiblingNodes<'a, T> { pub fn new(id: NodeId, arena: &'a Arena<T>) -> Self { SiblingNodes { first: id, arena } } } impl<T: Serialize> Serialize for SiblingNodes<'_, T> { fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { let mut seq = serializer.serialize_seq(None)?; for node in self.first.following_siblings(&self.arena) { seq.serialize_element(&Node::new(node, &self.arena))?; } seq.end() } }