openmls/treesync/
node.rs

1//! This module contains types and methods around the [`Node`] enum. The
2//! variants of the enum are `LeafNode` and [`ParentNode`], both of which are
3//! defined in the respective [`leaf_node`] and [`parent_node`] submodules.
4use serde::{Deserialize, Serialize};
5use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize};
6
7use self::{leaf_node::LeafNodeIn, parent_node::ParentNode};
8
9use super::LeafNode;
10
11mod codec;
12pub(crate) mod encryption_keys;
13pub(crate) mod leaf_node;
14pub(crate) mod parent_node;
15
16/// Container enum for leaf and parent nodes.
17///
18/// ```c
19/// struct {
20///     NodeType node_type;
21///     select (Node.node_type) {
22///         case leaf:   LeafNode leaf_node;
23///         case parent: ParentNode parent_node;
24///     };
25/// } Node;
26/// ```
27#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, TlsSize, TlsSerialize)]
28#[repr(u8)]
29pub enum Node {
30    /// A leaf node.
31    #[tls_codec(discriminant = 1)]
32    LeafNode(Box<LeafNode>),
33    /// A parent node.
34    #[tls_codec(discriminant = 2)]
35    ParentNode(Box<ParentNode>),
36}
37
38impl Node {
39    pub(crate) fn leaf_node(leaf: LeafNode) -> Self {
40        Self::LeafNode(Box::new(leaf))
41    }
42
43    pub(crate) fn parent_node(parent: ParentNode) -> Self {
44        Self::ParentNode(Box::new(parent))
45    }
46}
47
48#[derive(
49    Debug,
50    PartialEq,
51    Eq,
52    Clone,
53    Serialize,
54    Deserialize,
55    TlsSize,
56    TlsDeserialize,
57    TlsDeserializeBytes,
58    TlsSerialize,
59)]
60#[repr(u8)]
61pub enum NodeIn {
62    /// A leaf node.
63    #[tls_codec(discriminant = 1)]
64    LeafNode(Box<LeafNodeIn>),
65    /// A parent node.
66    #[tls_codec(discriminant = 2)]
67    ParentNode(Box<ParentNode>),
68}
69
70impl From<Node> for NodeIn {
71    fn from(node: Node) -> Self {
72        match node {
73            Node::LeafNode(leaf_node) => NodeIn::LeafNode(Box::new((*leaf_node).into())),
74            Node::ParentNode(parent_node) => NodeIn::ParentNode(parent_node),
75        }
76    }
77}
78
79// The following `From` implementation breaks abstraction layers and MUST
80// NOT be made available outside of tests or "test-utils".
81#[cfg(any(feature = "test-utils", test))]
82impl From<NodeIn> for Node {
83    fn from(node: NodeIn) -> Self {
84        match node {
85            NodeIn::LeafNode(leaf_node) => Node::LeafNode(Box::new((*leaf_node).into())),
86            NodeIn::ParentNode(parent_node) => Node::ParentNode(parent_node),
87        }
88    }
89}
90
91/// Container enum with reference to a node in a tree.
92pub(crate) enum NodeReference<'a> {
93    Leaf(&'a LeafNode),
94    Parent(&'a ParentNode),
95}