Skip to content

Commit 05edbe3

Browse files
committed
implement serde traits for ego-tree
1 parent da8049b commit 05edbe3

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,13 @@ authors = [
1111
license = "ISC"
1212
repository = "https://github.com/rust-scraper/ego-tree"
1313
readme = "README.md"
14+
15+
[features]
16+
serde = ["dep:serde"]
17+
18+
[dependencies]
19+
serde = { version = "1.0.209" , optional = true }
20+
21+
[dev-dependencies]
22+
serde = "1.0.209"
23+
serde_json = "1.0.127"

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
use std::fmt::{self, Debug, Display, Formatter};
3939
use std::num::NonZeroUsize;
4040

41+
#[cfg(feature = "serde")]
42+
/// Implement serde traits for Tree
43+
pub mod serde;
44+
4145
/// Vec-backed ID-tree.
4246
///
4347
/// Always contains at least a root node.

src/serde.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#![cfg(feature = "serde")]
2+
use std::num::NonZeroUsize;
3+
4+
use serde::{Deserialize, Serialize};
5+
6+
use crate::{Node, NodeId, Tree};
7+
8+
impl<T: Serialize> Serialize for Tree<T> {
9+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10+
where
11+
S: serde::Serializer,
12+
{
13+
self.vec.serialize(serializer)
14+
}
15+
}
16+
17+
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Tree<T> {
18+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
19+
where
20+
D: serde::Deserializer<'de>,
21+
{
22+
let vec = Vec::deserialize(deserializer)?;
23+
Ok(Tree { vec })
24+
}
25+
}
26+
27+
impl<T: Serialize> Serialize for Node<T> {
28+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29+
where
30+
S: serde::Serializer,
31+
{
32+
(
33+
&self.parent,
34+
&self.prev_sibling,
35+
&self.next_sibling,
36+
&self.children,
37+
&self.value,
38+
)
39+
.serialize(serializer)
40+
}
41+
}
42+
43+
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Node<T> {
44+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45+
where
46+
D: serde::Deserializer<'de>,
47+
{
48+
let (parent, prev_sibling, next_sibling, children, value) =
49+
<(
50+
Option<NodeId>,
51+
Option<NodeId>,
52+
Option<NodeId>,
53+
Option<(NodeId, NodeId)>,
54+
T,
55+
)>::deserialize(deserializer)?;
56+
Ok(Node {
57+
parent,
58+
prev_sibling,
59+
next_sibling,
60+
children,
61+
value,
62+
})
63+
}
64+
}
65+
66+
impl Serialize for NodeId {
67+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68+
where
69+
S: serde::Serializer,
70+
{
71+
self.0.serialize(serializer)
72+
}
73+
}
74+
75+
impl<'de> Deserialize<'de> for NodeId {
76+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77+
where
78+
D: serde::Deserializer<'de>,
79+
{
80+
let index = <NonZeroUsize>::deserialize(deserializer)?;
81+
Ok(NodeId(index))
82+
}
83+
}

tests/serde.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![cfg(feature = "serde")]
2+
#[macro_use]
3+
extern crate ego_tree;
4+
use std::assert_eq;
5+
6+
use ego_tree::Tree;
7+
8+
#[test]
9+
fn test_serialize() {
10+
let tree = tree!("r" => {"a", "b" => { "d", "e" }, "c"});
11+
12+
let serialized = serde_json::to_string(&tree).unwrap();
13+
let deserialized: Tree<&str> = serde_json::from_str(&serialized).unwrap();
14+
15+
assert_eq!(tree, deserialized);
16+
}

0 commit comments

Comments
 (0)