commit_bridge/domain/
commit_hash.rs1use crate::error::ValidationError;
4use rovo::schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
9#[serde(try_from = "String", into = "String")]
10pub struct CommitHash(String);
11
12impl CommitHash {
13 pub fn new(value: String) -> Result<Self, ValidationError> {
15 Self::try_from(value)
16 }
17
18 pub fn into_inner(self) -> String {
20 self.0
21 }
22
23 pub fn as_str(&self) -> &str {
25 &self.0
26 }
27}
28
29crate::derive_sqlx_traits!(CommitHash);
30
31impl AsRef<str> for CommitHash {
32 fn as_ref(&self) -> &str {
33 &self.0
34 }
35}
36
37impl std::fmt::Display for CommitHash {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(f, "{}", self.0)
40 }
41}
42
43impl TryFrom<String> for CommitHash {
44 type Error = ValidationError;
45
46 fn try_from(value: String) -> Result<Self, Self::Error> {
47 let len = value.len();
48 if len != 40 && len != 64 {
49 tracing::warn!(
50 "Validation failed for CommitHash: {}. Invalid length: {}",
51 value,
52 len
53 );
54 return Err(ValidationError::InvalidValue(format!(
55 "Commit hash must be 40 or 64 characters long. Got: {}",
56 len
57 )));
58 }
59
60 if !value.chars().all(|c| c.is_ascii_hexdigit()) {
61 tracing::warn!(
62 "Validation failed for CommitHash: {}. Non-hex characters",
63 value
64 );
65 return Err(ValidationError::InvalidValue(format!(
66 "Commit hash must be a hexadecimal string. Got: {}",
67 value
68 )));
69 }
70
71 Ok(CommitHash(value))
72 }
73}
74
75impl From<CommitHash> for String {
76 fn from(val: CommitHash) -> Self {
77 val.0
78 }
79}
80
81impl std::ops::Deref for CommitHash {
82 type Target = str;
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88
89impl PartialEq<str> for CommitHash {
90 fn eq(&self, other: &str) -> bool {
91 self.0 == other
92 }
93}
94
95impl PartialEq<CommitHash> for str {
96 fn eq(&self, other: &CommitHash) -> bool {
97 self == other.0
98 }
99}
100
101impl PartialEq<String> for CommitHash {
102 fn eq(&self, other: &String) -> bool {
103 &self.0 == other
104 }
105}
106
107impl PartialEq<CommitHash> for String {
108 fn eq(&self, other: &CommitHash) -> bool {
109 self == &other.0
110 }
111}