config_it/shared/
mod.rs

1//! Set of commonly used data structures.
2
3pub mod archive;
4pub mod meta;
5
6use serde::{Deserialize, Serialize};
7use std::hash::Hasher;
8
9macro_rules! id_type {
10    ($(#[doc = $doc:literal])* $id:ident $($args:tt)*) => {
11        $(#[doc = $doc])*
12        #[derive(
13            Debug,
14            Clone,
15            Copy,
16            Hash,
17            PartialEq,
18            Eq,
19            PartialOrd,
20            Ord,
21            derive_more::Display,
22            Serialize,
23            Deserialize
24            $($args)*
25        )]
26        pub struct $id(pub u64);
27    };
28}
29
30id_type!(
31    /// Represents a unique identifier for a storage instance.
32    StorageID,
33    derive_more::From
34);
35id_type!(
36    /// Represents a unique identifier for a path within the archive.
37    ///
38    /// This ID type is a wrapper around a 64-bit unsigned integer and is used to distinguish and
39    /// manage paths in a high-performance manner.
40    ///
41    /// As paths within the archive might be nested and represented hierarchically, having a unique
42    /// ID facilitates efficient operations such as lookup, comparison, and storage.
43    PathHash
44);
45id_type!(
46    /// Represents a unique identifier for a group within the storage.
47    ///
48    /// `GroupID` is primarily used to track, manage, and differentiate between different
49    /// configuration sets registered in storage. Each group is assigned a unique ID, ensuring
50    /// accurate management and operations upon it.
51    ///
52    /// This ID type also supports the `From` trait, which allows seamless conversion from certain
53    /// other types.
54    GroupID,
55    derive_more::From
56);
57id_type!(
58    /// Represents a unique identifier for an individual item or element.
59    ///
60    /// `ItemID` allows for the differentiation and management of individual configuration items
61    /// within the storage or a group. Each item, whether it's a variable, property, or another
62    /// entity, is assigned a unique ID for precise operations and management.
63    ///
64    /// The `From` trait support ensures that `ItemID` can be easily constructed from other relevant
65    /// types.
66    ItemID,
67    derive_more::From
68);
69
70impl PathHash {
71    /// Creates a new `PathHash` by hashing a sequence of path strings.
72    ///
73    /// This function takes an iterable of path strings and sequentially hashes each string to
74    /// produce a unique identifier in the form of `PathHash`. To ensure uniqueness and avoid
75    /// collisions between consecutive paths, a delimiter (`\x03\x00`) is written between each
76    /// hashed string.
77    ///
78    /// # Arguments
79    ///
80    /// * `paths` - An iterable of path strings that need to be hashed together to produce the
81    ///   `PathHash`.
82    ///
83    /// # Returns
84    ///
85    /// * A new `PathHash` which represents the hashed value of the concatenated path strings.
86    ///
87    /// # Example
88    ///
89    /// ```
90    /// let path_hash = config_it::shared::PathHash::new(["path1", "path2", "path3"]);
91    /// ```
92    pub fn new<'a>(paths: impl IntoIterator<Item = &'a str>) -> Self {
93        let mut hasher = std::collections::hash_map::DefaultHasher::new();
94        paths.into_iter().for_each(|x| {
95            hasher.write(x.as_bytes());
96            hasher.write(b"\x03\x00"); // delim
97        });
98        Self(hasher.finish())
99    }
100}
101
102impl<'a, T: IntoIterator<Item = &'a str>> From<T> for PathHash {
103    fn from(value: T) -> Self {
104        Self::new(value)
105    }
106}
107
108macro_rules! gen_new_fn {
109    ($type:path) => {
110        impl $type {
111            #[cfg(feature = "config")]
112            pub(crate) fn new_unique_incremental() -> Self {
113                static ID_GEN: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1);
114                Self(ID_GEN.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
115            }
116        }
117    };
118}
119
120gen_new_fn!(StorageID);
121gen_new_fn!(GroupID);
122gen_new_fn!(ItemID);