egml_core/model/base/
id.rs1use crate::Error;
2use sha2::{Digest, Sha256};
3use std::fmt;
4use std::fmt::Write;
5use uuid::Uuid;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub struct Id(String);
9
10impl Id {
11 pub fn from_hashed_bytes(val: impl AsRef<[u8]>) -> Self {
14 Self(Self::hash_bytes_to_hex(val.as_ref()))
15 }
16
17 pub fn from_hashed_string(val: &str) -> Self {
19 Self::from_hashed_bytes(val.as_bytes())
20 }
21
22 pub fn from_hashed_u64(val: u64) -> Self {
24 Self::from_hashed_bytes(val.to_le_bytes())
25 }
26
27 pub fn generate_uuid_v4() -> Self {
29 Self(Uuid::new_v4().to_string())
30 }
31}
32
33impl Id {
34 fn hash_bytes_to_hex(val: &[u8]) -> String {
36 let mut sha256 = Sha256::new();
37 sha256.update(val);
38 let result = sha256.finalize();
39
40 let mut hash = String::with_capacity(64);
42 for byte in result {
43 write!(&mut hash, "{:02X}", byte).unwrap();
44 }
45 hash
46 }
47}
48
49impl From<Id> for String {
50 fn from(item: Id) -> Self {
51 item.0
52 }
53}
54
55impl TryFrom<&String> for Id {
56 type Error = Error;
57
58 fn try_from(item: &String) -> Result<Self, Self::Error> {
59 if item.is_empty() {
60 Err(Error::MustNotBeEmpty("id"))
61 } else {
62 Ok(Self(item.to_string()))
63 }
64 }
65}
66
67impl TryFrom<&str> for Id {
68 type Error = Error;
69
70 fn try_from(item: &str) -> Result<Self, Self::Error> {
71 if item.is_empty() {
72 Err(Error::MustNotBeEmpty("id"))
73 } else {
74 Ok(Self(item.to_string()))
75 }
76 }
77}
78
79impl TryFrom<String> for Id {
80 type Error = Error;
81
82 fn try_from(item: String) -> Result<Self, Self::Error> {
83 if item.is_empty() {
84 Err(Error::MustNotBeEmpty("id"))
85 } else {
86 Ok(Self(item))
87 }
88 }
89}
90
91impl fmt::Display for Id {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 write!(f, "{}", self.0)
100 }
101}