Skip to content

Commit

Permalink
Merge pull request #13 from clementwanjau/feature/compact_serde
Browse files Browse the repository at this point in the history
Added the `compact serde` feature.
  • Loading branch information
clementwanjau authored Jul 9, 2024
2 parents 33529d7 + efd01e4 commit 8c6d2d7
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 160 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/Cargo.lock
/examples/*/target
/examples/*/Cargo.lock
*.sh
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- Added more bug fixes and tests.
- The auto id feature now depends on epoch based id generation to generate unique ids for nodes.
- Added a `print_node_id` feature to enable printing of node ids in the tree visualization. It is disabled by default.
- Added a `compact_serde` feature to enable compact serialization and deserialization of trees. It is disabled by
default.

## v0.1.4

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde = ["serde/std"] # The "serde" feature enables serialization and deserializ
auto_id = ["sequential_gen/default", "lazy_static/spin"] # This feature enables the automatic generation of unique identifiers for nodes.
no_std = ["sequential_gen/no_std", "lazy_static/spin_no_std", "serde/alloc"] # The "no_std" feature enables the use of the library in no_std environments.
print_node_id = [] # The "print_node_id" feature enables the printing of node identifiers in the Debug trait implementation of the Node struct.
compact_serde = [] # The "compact_serde" feature enables the serialization of the library's types in a compact format.

[dependencies]
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
Expand Down
20 changes: 20 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,30 @@
//! └── Node 4: 6
//! ```
//!
//! ## Serialization and Deserialization
//! The tree data structure can be serialized and deserialized using the `serde` feature. By default,
//! the tree serializes all the fields within the nodes. However, you can enable the `compact_serde`
//! feature to serialize only the important node data that is sufficient to properly deserialize the
//! node. This is useful when you want to serialize the tree and store it in a file or a database. The
//! `compact_serde` feature is meant to be used with either the `serde` or the `no_std` feature. Enabling
//! this feature without the `serde` or the `no_std` feature will result in nothing being serialized or
//! deserialized. It should be noted that this feature adds an overhead when deserializing the data since
//! the tree has to be reconstructed from the serialized data.
//!
//!
//! ## `no_std` Environments.
//! This crate can be used in `no_std` environments by enabling the `no_std` feature.
//!
//! ```toml
//! [dependencies]
//! tree-ds = { version = "0.1", features = ["no_std"] }
//! ```
//! The `no_std` feature disables the standard library and uses the `alloc` crate instead. The `alloc`
//! crate provides the necessary types for the tree data structure to work in `no_std` environments.
//! The `no_std` feature is useful when you want to use the tree data structure in embedded systems or
//! environments where the standard library is not available. This feature also supports serialization
//! and deserialization of the tree data structure as well as limited `auto_id` support.
//!
//!
//! ## Cargo Features
//! The following cargo features are also available:
Expand All @@ -123,6 +140,7 @@
//! - `auto_id`: Enables auto-generation of node IDs.
//! - `no_std`: Disables the standard library.
//! - `print_node_id`: Enables printing the node ID when printing the tree. It is disabled by default.
//! - `compact-serde`: Enables compact serialization and deserialization of the tree. It is meant to be used with either the `serde` or the `no_std` features. Enabling this feature without the `serde` or the `no_std` feature will result in nothing being serialized or deserialized.

#![cfg_attr(feature = "no_std", no_std)]

Expand All @@ -143,6 +161,7 @@ mod lib {
pub use alloc::rc::Rc;
#[cfg(all(feature = "no_std", feature = "async"))]
pub use alloc::sync::Arc;

#[cfg(not(feature = "no_std"))]
pub use std::{
collections::HashSet,
Expand Down Expand Up @@ -171,6 +190,7 @@ mod lib {
mod core {
#[cfg(feature = "no_std")]
pub use core::*;

#[cfg(not(feature = "no_std"))]
pub use std::*;
}
Expand Down
87 changes: 2 additions & 85 deletions src/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, ser::SerializeStruct, Serialize};

use crate::lib::*;
#[cfg(feature = "async")]
use crate::lib::Arc;
Expand All @@ -9,6 +6,8 @@ use crate::lib::Rc;

#[cfg(feature = "auto_id")]
mod auto_id;
#[cfg(feature = "serde")]
mod serde;

/// A node in a tree.
///
Expand Down Expand Up @@ -362,48 +361,7 @@ where
}
}

#[cfg(feature = "serde")]
impl<Q, T> Serialize for Node<Q, T>
where
Q: PartialEq + Eq + Clone + Serialize,
T: PartialEq + Eq + Clone + Serialize,
{
/// Serialize the node.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_struct("Node", 4)?;
state.serialize_field("node_id", &self.get_node_id())?;
state.serialize_field("value", &self.get_value())?;
state.serialize_field("children", &self.get_children_ids())?;
state.serialize_field("parent", &self.get_parent_id())?;
state.end()
}
}

#[cfg(feature = "serde")]
impl<'de, Q, T> Deserialize<'de> for Node<Q, T>
where
Q: PartialEq + Eq + Clone + Deserialize<'de>,
T: PartialEq + Eq + Clone + Deserialize<'de>,
{
/// Deserialize the node.
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let node: _Node<Q, T> = Deserialize::deserialize(deserializer)?;

#[cfg(not(feature = "async"))]
return Ok(Node(Rc::new(RefCell::new(node))));
#[cfg(feature = "async")]
return Ok(Node(Arc::new(RefCell::new(node))));
}
}

#[doc(hidden)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct _Node<Q, T>
where
Expand All @@ -429,7 +387,6 @@ where
///
/// * `Q` - The type of the unique id of the node.
/// * `T` - The type of the value of the node.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Nodes<Q, T>(Vec<Node<Q, T>>)
where
Expand Down Expand Up @@ -885,26 +842,6 @@ mod tests {
assert_eq!(format!("{}", node), "2");
}

#[cfg(feature = "serde")]
#[test]
fn test_node_serialize() {
let node = Node::new(1, Some(2));
let serialized = serde_json::to_string(&node).unwrap();
assert_eq!(
serialized,
r#"{"node_id":1,"value":2,"children":[],"parent":null}"#
);
}

#[cfg(feature = "serde")]
#[test]
fn test_node_deserialize() {
let node = Node::new(1, Some(2));
let serialized = serde_json::to_string(&node).unwrap();
let deserialized: Node<i32, i32> = serde_json::from_str(&serialized).unwrap();
assert_eq!(node, deserialized);
}

#[test]
fn test_nodes() {
let nodes = Nodes::new(vec![Node::new(1, Some(2))]);
Expand Down Expand Up @@ -1035,24 +972,4 @@ mod tests {
#[cfg(not(feature = "print_node_id"))]
assert_eq!(format!("{}", nodes), "2");
}

#[cfg(feature = "serde")]
#[test]
fn test_nodes_serialize() {
let nodes = Nodes::new(vec![Node::new(1, Some(2))]);
let serialized = serde_json::to_string(&nodes).unwrap();
assert_eq!(
serialized,
r#"[{"node_id":1,"value":2,"children":[],"parent":null}]"#
);
}

#[cfg(feature = "serde")]
#[test]
fn test_nodes_deserialize() {
let nodes = Nodes::new(vec![Node::new(1, Some(2))]);
let serialized = serde_json::to_string(&nodes).unwrap();
let deserialized: Nodes<i32, i32> = serde_json::from_str(&serialized).unwrap();
assert_eq!(nodes, deserialized);
}
}
Loading

0 comments on commit 8c6d2d7

Please sign in to comment.