raw
1use std::fmt;
2
3use serde::de::Error as _;
4use trim_in_place::TrimInPlace as _;
5
6pub(crate) struct Commit(pub String);
7
8impl fmt::Display for Commit {
9 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10 self.0.fmt(f)
11 }
12}
13
14impl<'de> serde::Deserialize<'de> for Commit {
15 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
16 where
17 D: serde::Deserializer<'de>,
18 {
19 let mut value = String::deserialize(deserializer)?;
20
21 value.trim_in_place();
22
23 if value.is_empty() || value.starts_with('.') {
24 return Err(D::Error::custom("invalid commit ref"));
25 }
26
27 for c in value.bytes() {
28 if !c.is_ascii_hexdigit() {
29 return Err(D::Error::custom("invalid commit ref"));
30 }
31 }
32
33 Ok(Self(value))
34 }
35}
36
37pub(crate) struct Obj(pub String);
38
39impl fmt::Display for Obj {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 self.0.fmt(f)
42 }
43}
44
45impl<'de> serde::Deserialize<'de> for Obj {
46 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
47 where
48 D: serde::Deserializer<'de>,
49 {
50 let mut value = String::deserialize(deserializer)?;
51
52 value.trim_in_place();
53
54 if value.is_empty() {
55 return Err(D::Error::custom("invalid object ref"));
56 }
57
58 Ok(Self(value))
59 }
60}
61
62pub(crate) struct ObjectName(pub String);
63
64impl fmt::Display for ObjectName {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 self.0.fmt(f)
67 }
68}
69
70impl<'de> serde::Deserialize<'de> for ObjectName {
71 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
72 where
73 D: serde::Deserializer<'de>,
74 {
75 let mut value = String::deserialize(deserializer)?;
76
77 value.trim_in_place();
78
79 if value.is_empty() {
80 return Err(D::Error::custom("invalid object name"));
81 }
82
83 Ok(Self(value))
84 }
85}
86
87pub(crate) struct Ref(pub String);
88
89impl fmt::Display for Ref {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 self.0.fmt(f)
92 }
93}
94
95impl<'de> serde::Deserialize<'de> for Ref {
96 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97 where
98 D: serde::Deserializer<'de>,
99 {
100 let mut value = String::deserialize(deserializer)?;
101
102 value.trim_in_place();
103
104 if value.is_empty() || value.starts_with('.') {
105 return Err(D::Error::custom("invalid ref"));
106 }
107
108 Ok(Self(value))
109 }
110}
111
112pub(crate) struct RepoName(pub String);
113
114impl fmt::Display for RepoName {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 self.0.fmt(f)
117 }
118}
119
120impl<'de> serde::Deserialize<'de> for RepoName {
121 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
122 where
123 D: serde::Deserializer<'de>,
124 {
125 let mut value = String::deserialize(deserializer)?;
126
127 value.trim_in_place();
128
129 if value.is_empty() || value.starts_with('.') {
130 return Err(D::Error::custom("invalid repo name"));
131 }
132
133 Ok(Self(value))
134 }
135}
136
137pub(crate) struct Tag(pub String);
138
139impl fmt::Display for Tag {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 self.0.fmt(f)
142 }
143}
144
145impl<'de> serde::Deserialize<'de> for Tag {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: serde::Deserializer<'de>,
149 {
150 let mut value = String::deserialize(deserializer)?;
151
152 value.trim_in_place();
153
154 if value.is_empty() {
155 return Err(D::Error::custom("invalid tag"));
156 }
157
158 Ok(Self(value))
159 }
160}
161