1use std::borrow::Borrow;
35use std::fmt;
36use std::fmt::Display;
37use std::ops::Deref;
38
39use ref_cast::RefCastCustom;
40use ref_cast::ref_cast_custom;
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, serde::Serialize)]
99#[serde(transparent)]
100pub struct WorkspaceNameBuf(String);
101
102#[derive(
107 ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom, serde::Serialize,
108)]
109#[serde(transparent)]
110#[repr(transparent)]
111pub struct WorkspaceName(str);
112
113macro_rules! impl_partial_eq {
114 ($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
115 impl PartialEq<$rhs> for $lhs {
116 fn eq(&self, other: &$rhs) -> bool {
117 <$borrowed_ty as PartialEq>::eq(self, other)
118 }
119 }
120
121 impl PartialEq<$lhs> for $rhs {
122 fn eq(&self, other: &$lhs) -> bool {
123 <$borrowed_ty as PartialEq>::eq(self, other)
124 }
125 }
126 };
127}
128
129macro_rules! impl_partial_eq_str {
130 ($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
131 impl PartialEq<$rhs> for $lhs {
132 fn eq(&self, other: &$rhs) -> bool {
133 <$borrowed_ty as PartialEq>::eq(self, other.as_ref())
134 }
135 }
136
137 impl PartialEq<$lhs> for $rhs {
138 fn eq(&self, other: &$lhs) -> bool {
139 <$borrowed_ty as PartialEq>::eq(self.as_ref(), other)
140 }
141 }
142 };
143}
144
145macro_rules! impl_name_type {
146 ($owned_ty:ident, $borrowed_ty:ident) => {
147 impl $owned_ty {
148 pub fn into_string(self) -> String {
150 self.0
151 }
152 }
153
154 impl $borrowed_ty {
155 #[ref_cast_custom]
157 pub const fn new(name: &str) -> &Self;
158
159 pub const fn as_str(&self) -> &str {
161 &self.0
162 }
163
164 pub fn as_symbol(&self) -> &RefSymbol {
166 RefSymbol::new(&self.0)
167 }
168 }
169
170 impl From<String> for $owned_ty {
173 fn from(value: String) -> Self {
174 $owned_ty(value)
175 }
176 }
177
178 impl From<&String> for $owned_ty {
179 fn from(value: &String) -> Self {
180 $owned_ty(value.clone())
181 }
182 }
183
184 impl From<&str> for $owned_ty {
185 fn from(value: &str) -> Self {
186 $owned_ty(value.to_owned())
187 }
188 }
189
190 impl From<&$owned_ty> for $owned_ty {
193 fn from(value: &$owned_ty) -> Self {
194 value.clone()
195 }
196 }
197
198 impl From<&$borrowed_ty> for $owned_ty {
199 fn from(value: &$borrowed_ty) -> Self {
200 value.to_owned()
201 }
202 }
203
204 impl AsRef<$borrowed_ty> for String {
207 fn as_ref(&self) -> &$borrowed_ty {
208 $borrowed_ty::new(self)
209 }
210 }
211
212 impl AsRef<$borrowed_ty> for str {
213 fn as_ref(&self) -> &$borrowed_ty {
214 $borrowed_ty::new(self)
215 }
216 }
217
218 impl From<$owned_ty> for String {
221 fn from(value: $owned_ty) -> Self {
222 value.0
223 }
224 }
225
226 impl From<&$owned_ty> for String {
227 fn from(value: &$owned_ty) -> Self {
228 value.0.clone()
229 }
230 }
231
232 impl From<&$borrowed_ty> for String {
233 fn from(value: &$borrowed_ty) -> Self {
234 value.0.to_owned()
235 }
236 }
237
238 impl AsRef<str> for $owned_ty {
239 fn as_ref(&self) -> &str {
240 self.as_str()
241 }
242 }
243
244 impl AsRef<str> for $borrowed_ty {
245 fn as_ref(&self) -> &str {
246 self.as_str()
247 }
248 }
249
250 impl AsRef<$borrowed_ty> for $owned_ty {
253 fn as_ref(&self) -> &$borrowed_ty {
254 self
255 }
256 }
257
258 impl AsRef<$borrowed_ty> for $borrowed_ty {
259 fn as_ref(&self) -> &$borrowed_ty {
260 self
261 }
262 }
263
264 impl Borrow<$borrowed_ty> for $owned_ty {
265 fn borrow(&self) -> &$borrowed_ty {
266 self
267 }
268 }
269
270 impl Deref for $owned_ty {
271 type Target = $borrowed_ty;
272
273 fn deref(&self) -> &Self::Target {
274 $borrowed_ty::new(&self.0)
275 }
276 }
277
278 impl ToOwned for $borrowed_ty {
279 type Owned = $owned_ty;
280
281 fn to_owned(&self) -> Self::Owned {
282 $owned_ty(self.0.to_owned())
283 }
284 }
285
286 impl_partial_eq!($borrowed_ty, $owned_ty, $borrowed_ty);
288 impl_partial_eq!($borrowed_ty, $owned_ty, &$borrowed_ty);
289
290 impl_partial_eq_str!($borrowed_ty, $owned_ty, str);
292 impl_partial_eq_str!($borrowed_ty, $owned_ty, &str);
293 impl_partial_eq_str!($borrowed_ty, $owned_ty, String);
294 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, str);
295 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, &str);
296 impl_partial_eq_str!($borrowed_ty, $borrowed_ty, String);
297 impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, str);
298 impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, String);
299 };
300}
301
302impl_name_type!(GitRefNameBuf, GitRefName);
303impl_name_type!(RefNameBuf, RefName);
306impl_name_type!(RemoteNameBuf, RemoteName);
307impl_name_type!(WorkspaceNameBuf, WorkspaceName);
308
309impl RefName {
310 pub fn to_remote_symbol<'a>(&'a self, remote: &'a RemoteName) -> RemoteRefSymbol<'a> {
312 RemoteRefSymbol { name: self, remote }
313 }
314}
315
316impl WorkspaceName {
317 pub const DEFAULT: &Self = Self::new("default");
319}
320
321#[derive(Debug, RefCastCustom)]
325#[repr(transparent)]
326pub struct RefSymbol(str);
327
328impl RefSymbol {
329 #[ref_cast_custom]
331 const fn new(name: &str) -> &Self;
332}
333
334impl Display for RefSymbol {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 f.pad(&revset::format_symbol(&self.0))
337 }
338}
339
340#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
345pub struct RemoteRefSymbolBuf {
346 pub name: RefNameBuf,
348 pub remote: RemoteNameBuf,
350}
351
352impl RemoteRefSymbolBuf {
353 pub fn as_ref(&self) -> RemoteRefSymbol<'_> {
355 RemoteRefSymbol {
356 name: &self.name,
357 remote: &self.remote,
358 }
359 }
360}
361
362#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
367pub struct RemoteRefSymbol<'a> {
368 pub name: &'a RefName,
370 pub remote: &'a RemoteName,
372}
373
374impl RemoteRefSymbol<'_> {
375 pub fn to_owned(self) -> RemoteRefSymbolBuf {
377 RemoteRefSymbolBuf {
378 name: self.name.to_owned(),
379 remote: self.remote.to_owned(),
380 }
381 }
382}
383
384impl From<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
385 fn from(value: RemoteRefSymbol<'_>) -> Self {
386 value.to_owned()
387 }
388}
389
390impl PartialEq<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
391 fn eq(&self, other: &RemoteRefSymbol) -> bool {
392 self.as_ref() == *other
393 }
394}
395
396impl PartialEq<RemoteRefSymbol<'_>> for &RemoteRefSymbolBuf {
397 fn eq(&self, other: &RemoteRefSymbol) -> bool {
398 self.as_ref() == *other
399 }
400}
401
402impl PartialEq<RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
403 fn eq(&self, other: &RemoteRefSymbolBuf) -> bool {
404 *self == other.as_ref()
405 }
406}
407
408impl PartialEq<&RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
409 fn eq(&self, other: &&RemoteRefSymbolBuf) -> bool {
410 *self == other.as_ref()
411 }
412}
413
414impl Display for RemoteRefSymbolBuf {
415 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416 Display::fmt(&self.as_ref(), f)
417 }
418}
419
420impl Display for RemoteRefSymbol<'_> {
421 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422 let RemoteRefSymbol { name, remote } = self;
423 f.pad(&revset::format_remote_symbol(&name.0, &remote.0))
424 }
425}