1use std::borrow::Borrow;
35use std::fmt;
36use std::fmt::Display;
37use std::ops::Deref;
38
39use ref_cast::ref_cast_custom;
40use ref_cast::RefCastCustom;
41
42use crate::content_hash::ContentHash;
43use crate::revset;
44
45#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
51pub struct GitRefNameBuf(String);
52
53#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
58#[repr(transparent)]
59pub struct GitRefName(str);
60
61#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
67pub struct RefNameBuf(String);
68
69#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
74#[repr(transparent)]
75pub struct RefName(str);
76
77#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
83pub struct RemoteNameBuf(String);
84
85#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
90#[repr(transparent)]
91pub struct RemoteName(str);
92
93#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
99pub struct WorkspaceNameBuf(String);
100
101#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
106#[repr(transparent)]
107pub struct WorkspaceName(str);
108
109macro_rules! impl_partial_eq {
110 ($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
111 impl PartialEq<$rhs> for $lhs {
112 fn eq(&self, other: &$rhs) -> bool {
113 <$borrowed_ty as PartialEq>::eq(self, other)
114 }
115 }
116
117 impl PartialEq<$lhs> for $rhs {
118 fn eq(&self, other: &$lhs) -> bool {
119 <$borrowed_ty as PartialEq>::eq(self, other)
120 }
121 }
122 };
123}
124
125macro_rules! impl_partial_eq_str {
126 ($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
127 impl PartialEq<$rhs> for $lhs {
128 fn eq(&self, other: &$rhs) -> bool {
129 <$borrowed_ty as PartialEq>::eq(self, other.as_ref())
130 }
131 }
132
133 impl PartialEq<$lhs> for $rhs {
134 fn eq(&self, other: &$lhs) -> bool {
135 <$borrowed_ty as PartialEq>::eq(self.as_ref(), other)
136 }
137 }
138 };
139}
140
141macro_rules! impl_name_type {
142 ($owned_ty:ident, $borrowed_ty:ident) => {
143 impl $owned_ty {
144 pub fn into_string(self) -> String {
146 self.0
147 }
148 }
149
150 impl $borrowed_ty {
151 #[ref_cast_custom]
153 pub const fn new(name: &str) -> &Self;
154
155 pub const fn as_str(&self) -> &str {
157 &self.0
158 }
159
160 pub fn as_symbol(&self) -> &RefSymbol {
162 RefSymbol::new(&self.0)
163 }
164 }
165
166 impl From<String> for $owned_ty {
169 fn from(value: String) -> Self {
170 $owned_ty(value)
171 }
172 }
173
174 impl From<&String> for $owned_ty {
175 fn from(value: &String) -> Self {
176 $owned_ty(value.clone())
177 }
178 }
179
180 impl From<&str> for $owned_ty {
181 fn from(value: &str) -> Self {
182 $owned_ty(value.to_owned())
183 }
184 }
185
186 impl From<&$owned_ty> for $owned_ty {
189 fn from(value: &$owned_ty) -> Self {
190 value.clone()
191 }
192 }
193
194 impl From<&$borrowed_ty> for $owned_ty {
195 fn from(value: &$borrowed_ty) -> Self {
196 value.to_owned()
197 }
198 }
199
200 impl AsRef<$borrowed_ty> for String {
203 fn as_ref(&self) -> &$borrowed_ty {
204 $borrowed_ty::new(self)
205 }
206 }
207
208 impl AsRef<$borrowed_ty> for str {
209 fn as_ref(&self) -> &$borrowed_ty {
210 $borrowed_ty::new(self)
211 }
212 }
213
214 impl From<$owned_ty> for String {
217 fn from(value: $owned_ty) -> Self {
218 value.0
219 }
220 }
221
222 impl From<&$owned_ty> for String {
223 fn from(value: &$owned_ty) -> Self {
224 value.0.clone()
225 }
226 }
227
228 impl From<&$borrowed_ty> for String {
229 fn from(value: &$borrowed_ty) -> Self {
230 value.0.to_owned()
231 }
232 }
233
234 impl AsRef<str> for $owned_ty {
235 fn as_ref(&self) -> &str {
236 self.as_str()
237 }
238 }
239
240 impl AsRef<str> for $borrowed_ty {
241 fn as_ref(&self) -> &str {
242 self.as_str()
243 }
244 }
245
246 impl AsRef<$borrowed_ty> for $owned_ty {
249 fn as_ref(&self) -> &$borrowed_ty {
250 self
251 }
252 }
253
254 impl AsRef<$borrowed_ty> for $borrowed_ty {
255 fn as_ref(&self) -> &$borrowed_ty {
256 self
257 }
258 }
259
260 impl Borrow<$borrowed_ty> for $owned_ty {
261 fn borrow(&self) -> &$borrowed_ty {
262 self
263 }
264 }
265
266 impl Deref for $owned_ty {
267 type Target = $borrowed_ty;
268
269 fn deref(&self) -> &Self::Target {
270 $borrowed_ty::new(&self.0)
271 }
272 }
273
274 impl ToOwned for $borrowed_ty {
275 type Owned = $owned_ty;
276
277 fn to_owned(&self) -> Self::Owned {
278 $owned_ty(self.0.to_owned())
279 }
280 }
281
282 impl_partial_eq!($borrowed_ty, $owned_ty, $borrowed_ty);
284 impl_partial_eq!($borrowed_ty, $owned_ty, &$borrowed_ty);
285
286 impl_partial_eq_str!($borrowed_ty, $owned_ty, str);
288 impl_partial_eq_str!($borrowed_ty, $owned_ty, &str);
289 impl_partial_eq_str!($borrowed_ty, $owned_ty, String);
290 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, str);
291 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, &str);
292 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, String);
293 impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, str);
294 impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, String);
295 };
296}
297
298impl_name_type!(GitRefNameBuf, GitRefName);
299impl_name_type!(RefNameBuf, RefName);
302impl_name_type!(RemoteNameBuf, RemoteName);
303impl_name_type!(WorkspaceNameBuf, WorkspaceName);
304
305impl RefName {
306 pub fn to_remote_symbol<'a>(&'a self, remote: &'a RemoteName) -> RemoteRefSymbol<'a> {
308 RemoteRefSymbol { name: self, remote }
309 }
310}
311
312impl WorkspaceName {
313 pub const DEFAULT: &WorkspaceName = WorkspaceName::new("default");
315}
316
317#[derive(Debug, RefCastCustom)]
321#[repr(transparent)]
322pub struct RefSymbol(str);
323
324impl RefSymbol {
325 #[ref_cast_custom]
327 const fn new(name: &str) -> &Self;
328}
329
330impl Display for RefSymbol {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 f.pad(&revset::format_symbol(&self.0))
333 }
334}
335
336#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
341pub struct RemoteRefSymbolBuf {
342 pub name: RefNameBuf,
344 pub remote: RemoteNameBuf,
346}
347
348impl RemoteRefSymbolBuf {
349 pub fn as_ref(&self) -> RemoteRefSymbol<'_> {
351 RemoteRefSymbol {
352 name: &self.name,
353 remote: &self.remote,
354 }
355 }
356}
357
358#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
363pub struct RemoteRefSymbol<'a> {
364 pub name: &'a RefName,
366 pub remote: &'a RemoteName,
368}
369
370impl RemoteRefSymbol<'_> {
371 pub fn to_owned(self) -> RemoteRefSymbolBuf {
373 RemoteRefSymbolBuf {
374 name: self.name.to_owned(),
375 remote: self.remote.to_owned(),
376 }
377 }
378}
379
380impl From<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
381 fn from(value: RemoteRefSymbol<'_>) -> Self {
382 value.to_owned()
383 }
384}
385
386impl PartialEq<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
387 fn eq(&self, other: &RemoteRefSymbol) -> bool {
388 self.as_ref() == *other
389 }
390}
391
392impl PartialEq<RemoteRefSymbol<'_>> for &RemoteRefSymbolBuf {
393 fn eq(&self, other: &RemoteRefSymbol) -> bool {
394 self.as_ref() == *other
395 }
396}
397
398impl PartialEq<RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
399 fn eq(&self, other: &RemoteRefSymbolBuf) -> bool {
400 *self == other.as_ref()
401 }
402}
403
404impl PartialEq<&RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
405 fn eq(&self, other: &&RemoteRefSymbolBuf) -> bool {
406 *self == other.as_ref()
407 }
408}
409
410impl Display for RemoteRefSymbolBuf {
411 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
412 Display::fmt(&self.as_ref(), f)
413 }
414}
415
416impl Display for RemoteRefSymbol<'_> {
417 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
418 let RemoteRefSymbol { name, remote } = self;
419 f.pad(&revset::format_remote_symbol(&name.0, &remote.0))
420 }
421}