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