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/// // draft-ietf-mls-protocol-17
20/// struct {
21///     NodeType node_type;
22///     select (Node.node_type) {
23///         case leaf:   LeafNode leaf_node;
24///         case parent: ParentNode parent_node;
25///     };
26/// } Node;
27/// ```
28#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, TlsSize, TlsSerialize)]
29// TODO: #1670 to remove this `allow`
30#[allow(clippy::large_enum_variant)]
31#[repr(u8)]
32pub enum Node {
33    /// A leaf node.
34    #[tls_codec(discriminant = 1)]
35    LeafNode(LeafNode),
36    /// A parent node.
37    #[tls_codec(discriminant = 2)]
38    ParentNode(ParentNode),
39}
40
41#[derive(
42    Debug,
43    PartialEq,
44    Eq,
45    Clone,
46    Serialize,
47    Deserialize,
48    TlsSize,
49    TlsDeserialize,
50    TlsDeserializeBytes,
51    TlsSerialize,
52)]
53// TODO: #1670 to remove this `allow`
54#[allow(clippy::large_enum_variant)]
55#[repr(u8)]
56pub enum NodeIn {
57    /// A leaf node.
58    #[tls_codec(discriminant = 1)]
59    LeafNode(LeafNodeIn),
60    /// A parent node.
61    #[tls_codec(discriminant = 2)]
62    ParentNode(ParentNode),
63}
64
65impl From<Node> for NodeIn {
66    fn from(node: Node) -> Self {
67        match node {
68            Node::LeafNode(leaf_node) => NodeIn::LeafNode(leaf_node.into()),
69            Node::ParentNode(parent_node) => NodeIn::ParentNode(parent_node),
70        }
71    }
72}
73
74// The following `From` implementation breaks abstraction layers and MUST
75// NOT be made available outside of tests or "test-utils".
76#[cfg(any(feature = "test-utils", test))]
77impl From<NodeIn> for Node {
78    fn from(node: NodeIn) -> Self {
79        match node {
80            NodeIn::LeafNode(leaf_node) => Node::LeafNode(leaf_node.into()),
81            NodeIn::ParentNode(parent_node) => Node::ParentNode(parent_node),
82        }
83    }
84}
85
86/// Container enum with reference to a node in a tree.
87pub(crate) enum NodeReference<'a> {
88    Leaf(&'a LeafNode),
89    Parent(&'a ParentNode),
90}
91
92#[cfg(test)]
93impl Node {
94    #[allow(unused)]
95    pub(crate) fn into_leaf(self) -> LeafNode {
96        match self {
97            Node::LeafNode(l) => l,
98            Node::ParentNode(_) => panic!("Tried to convert parent node into leaf node."),
99        }
100    }
101}