radicle_git_ref_format/
lib.rs1#![no_std]
2
3pub use git_ref_format_core::*;
29
30#[cfg(any(feature = "macro", test))]
36#[macro_export]
37macro_rules! refname {
38 ($arg:literal) => {{
39 use $crate::RefString;
40
41 #[cfg(debug_assertions)]
42 {
43 RefString::try_from($arg).expect(core::concat!(
44 "literal `",
45 $arg,
46 "` must be a valid reference name"
47 ))
48 }
49
50 #[cfg(not(debug_assertions))]
51 {
52 extern crate alloc;
53
54 use alloc::string::String;
55
56 let s: String = $arg.to_owned();
57 unsafe { core::mem::transmute::<_, RefString>(s) }
58 }
59 }};
60}
61
62#[cfg(any(feature = "macro", test))]
68#[macro_export]
69macro_rules! qualified {
70 ($arg:literal) => {{
71 use $crate::Qualified;
72
73 #[cfg(debug_assertions)]
74 {
75 Qualified::from_refstr($crate::refname!($arg)).expect(core::concat!(
76 "literal `",
77 $arg,
78 "` must be of the form 'refs/<category>/<name>'"
79 ))
80 }
81
82 #[cfg(not(debug_assertions))]
83 {
84 extern crate alloc;
85
86 use core::mem::transmute;
87
88 use alloc::borrow::Cow;
89 use alloc::string::String;
90
91 use $crate::{RefStr, RefString};
92
93 let s: String = $arg.to_owned();
94 let refstring: RefString = unsafe { transmute(s) };
95 let cow: Cow<'_, RefStr> = Cow::Owned(refstring);
96 let qualified: Qualified = unsafe { transmute(cow) };
97
98 qualified
99 }
100 }};
101}
102
103#[cfg(any(feature = "macro", test))]
109#[macro_export]
110macro_rules! component {
111 ($arg:literal) => {{
112 use $crate::Component;
113
114 #[cfg(debug_assertions)]
115 {
116 Component::from_refstr($crate::refname!($arg)).expect(core::concat!(
117 "literal `",
118 $arg,
119 "` must be a valid component (cannot contain '/')"
120 ))
121 }
122
123 #[cfg(not(debug_assertions))]
124 {
125 extern crate alloc;
126
127 use core::mem::transmute;
128
129 use alloc::borrow::Cow;
130 use alloc::string::String;
131
132 use $crate::{RefStr, RefString};
133
134 let s: String = $arg.to_owned();
135 let refstring: RefString = unsafe { transmute(s) };
136 let cow: Cow<'_, RefStr> = Cow::Owned(refstring);
137 let component: Component = unsafe { transmute(cow) };
138
139 component
140 }
141 }};
142}
143
144#[cfg(any(feature = "macro", test))]
150#[macro_export]
151macro_rules! pattern {
152 ($arg:literal) => {{
153 use $crate::refspec::PatternString;
154
155 #[cfg(debug_assertions)]
156 {
157 PatternString::try_from($arg).expect(core::concat!(
158 "literal `",
159 $arg,
160 "` must be a valid refspec pattern"
161 ))
162 }
163
164 #[cfg(not(debug_assertions))]
165 {
166 extern crate alloc;
167
168 use alloc::string::String;
169
170 let s: String = $arg.to_owned();
171 unsafe { core::mem::transmute::<_, PatternString>(s) }
172 }
173 }};
174}
175
176#[cfg(any(feature = "macro", test))]
182#[macro_export]
183macro_rules! qualified_pattern {
184 ($arg:literal) => {{
185 use $crate::refspec::QualifiedPattern;
186
187 #[cfg(debug_assertions)]
188 {
189 use core::concat;
190
191 use $crate::refspec::PatternStr;
192
193 let pattern = PatternStr::try_from_str($arg).expect(concat!(
194 "literal `",
195 $arg,
196 "` must be a valid refspec pattern"
197 ));
198
199 QualifiedPattern::from_patternstr(pattern).expect(concat!(
200 "literal `",
201 $arg,
202 "` must be a valid qualified refspec pattern"
203 ))
204 }
205
206 #[cfg(not(debug_assertions))]
207 {
208 extern crate alloc;
209
210 use core::mem::transmute;
211
212 use alloc::borrow::Cow;
213 use alloc::string::String;
214
215 use $crate::refspec::{PatternStr, PatternString};
216
217 let s: String = $arg.to_owned();
218 let pattern: PatternString = unsafe { transmute(s) };
219 let cow: Cow<'_, PatternStr> = Cow::Owned(pattern);
220 let qualified: QualifiedPattern = unsafe { transmute(cow) };
221
222 qualified
223 }
224 }};
225}
226
227#[cfg(test)]
228mod test {
229 #[test]
230 fn refname() {
231 let _ = crate::refname!("refs/heads/main");
232 let _ = crate::refname!("refs/tags/v1.0.0");
233 let _ = crate::refname!("refs/remotes/origin/main");
234 let _ = crate::refname!("a");
235 }
236
237 #[test]
238 #[should_panic]
239 fn refname_invalid() {
240 let _ = crate::refname!("a~b");
241 }
242
243 #[test]
244 fn qualified() {
245 let _ = crate::qualified!("refs/heads/main");
246 let _ = crate::qualified!("refs/tags/v1.0.0");
247 let _ = crate::qualified!("refs/remotes/origin/main");
248 }
249
250 #[test]
251 #[should_panic]
252 fn qualified_invalid() {
253 let _ = crate::qualified!("a");
254 }
255
256 #[test]
257 fn component() {
258 let _ = crate::component!("a");
259 }
260
261 #[test]
262 #[should_panic]
263 fn component_invalid() {
264 let _ = crate::component!("a/b");
265 }
266
267 #[test]
268 fn pattern() {
269 let _ = crate::pattern!("refs/heads/main");
270 let _ = crate::pattern!("refs/tags/v1.0.0");
271 let _ = crate::pattern!("refs/remotes/origin/main");
272
273 let _ = crate::pattern!("a");
274 let _ = crate::pattern!("a/*");
275 let _ = crate::pattern!("*");
276 let _ = crate::pattern!("a/b*");
277 let _ = crate::pattern!("a/b*/c");
278 let _ = crate::pattern!("a/*/c");
279 }
280
281 #[test]
282 fn qualified_pattern() {
283 let _ = crate::qualified_pattern!("refs/heads/main");
284 let _ = crate::qualified_pattern!("refs/tags/v1.0.0");
285 let _ = crate::qualified_pattern!("refs/remotes/origin/main");
286
287 let _ = crate::qualified_pattern!("refs/heads/main/*");
288 let _ = crate::qualified_pattern!("refs/tags/v*");
289 let _ = crate::qualified_pattern!("refs/remotes/origin/main");
290 let _ = crate::qualified_pattern!("refs/remotes/origin/department/*/person");
291 }
292
293 #[test]
294 #[should_panic]
295 fn qualified_pattern_invalid() {
296 let _ = crate::qualified_pattern!("a/*/b");
297 }
298}