use std::borrow::Borrow;
use std::fmt;
use std::fmt::Display;
use std::ops::Deref;
use ref_cast::RefCastCustom;
use ref_cast::ref_cast_custom;
use crate::content_hash::ContentHash;
use crate::revset;
#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct GitRefNameBuf(String);
#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
#[repr(transparent)]
pub struct GitRefName(str);
#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RefNameBuf(String);
#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
#[repr(transparent)]
pub struct RefName(str);
#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RemoteNameBuf(String);
#[derive(ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom)]
#[repr(transparent)]
pub struct RemoteName(str);
#[derive(Clone, ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Serialize)]
#[serde(transparent)]
pub struct WorkspaceNameBuf(String);
#[derive(
ContentHash, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, RefCastCustom, serde::Serialize,
)]
#[serde(transparent)]
#[repr(transparent)]
pub struct WorkspaceName(str);
macro_rules! impl_partial_eq {
($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
impl PartialEq<$rhs> for $lhs {
fn eq(&self, other: &$rhs) -> bool {
<$borrowed_ty as PartialEq>::eq(self, other)
}
}
impl PartialEq<$lhs> for $rhs {
fn eq(&self, other: &$lhs) -> bool {
<$borrowed_ty as PartialEq>::eq(self, other)
}
}
};
}
macro_rules! impl_partial_eq_str {
($borrowed_ty:ty, $lhs:ty, $rhs:ty) => {
impl PartialEq<$rhs> for $lhs {
fn eq(&self, other: &$rhs) -> bool {
<$borrowed_ty as PartialEq>::eq(self, other.as_ref())
}
}
impl PartialEq<$lhs> for $rhs {
fn eq(&self, other: &$lhs) -> bool {
<$borrowed_ty as PartialEq>::eq(self.as_ref(), other)
}
}
};
}
macro_rules! impl_name_type {
($owned_ty:ident, $borrowed_ty:ident) => {
impl $owned_ty {
pub fn into_string(self) -> String {
self.0
}
}
impl $borrowed_ty {
#[ref_cast_custom]
pub const fn new(name: &str) -> &Self;
pub const fn as_str(&self) -> &str {
&self.0
}
pub fn as_symbol(&self) -> &RefSymbol {
RefSymbol::new(&self.0)
}
}
impl From<String> for $owned_ty {
fn from(value: String) -> Self {
$owned_ty(value)
}
}
impl From<&String> for $owned_ty {
fn from(value: &String) -> Self {
$owned_ty(value.clone())
}
}
impl From<&str> for $owned_ty {
fn from(value: &str) -> Self {
$owned_ty(value.to_owned())
}
}
impl From<&$owned_ty> for $owned_ty {
fn from(value: &$owned_ty) -> Self {
value.clone()
}
}
impl From<&$borrowed_ty> for $owned_ty {
fn from(value: &$borrowed_ty) -> Self {
value.to_owned()
}
}
impl AsRef<$borrowed_ty> for String {
fn as_ref(&self) -> &$borrowed_ty {
$borrowed_ty::new(self)
}
}
impl AsRef<$borrowed_ty> for str {
fn as_ref(&self) -> &$borrowed_ty {
$borrowed_ty::new(self)
}
}
impl From<$owned_ty> for String {
fn from(value: $owned_ty) -> Self {
value.0
}
}
impl From<&$owned_ty> for String {
fn from(value: &$owned_ty) -> Self {
value.0.clone()
}
}
impl From<&$borrowed_ty> for String {
fn from(value: &$borrowed_ty) -> Self {
value.0.to_owned()
}
}
impl AsRef<str> for $owned_ty {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl AsRef<str> for $borrowed_ty {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl AsRef<$borrowed_ty> for $owned_ty {
fn as_ref(&self) -> &$borrowed_ty {
self
}
}
impl AsRef<$borrowed_ty> for $borrowed_ty {
fn as_ref(&self) -> &$borrowed_ty {
self
}
}
impl Borrow<$borrowed_ty> for $owned_ty {
fn borrow(&self) -> &$borrowed_ty {
self
}
}
impl Deref for $owned_ty {
type Target = $borrowed_ty;
fn deref(&self) -> &Self::Target {
$borrowed_ty::new(&self.0)
}
}
impl ToOwned for $borrowed_ty {
type Owned = $owned_ty;
fn to_owned(&self) -> Self::Owned {
$owned_ty(self.0.to_owned())
}
}
impl_partial_eq!($borrowed_ty, $owned_ty, $borrowed_ty);
impl_partial_eq!($borrowed_ty, $owned_ty, &$borrowed_ty);
impl_partial_eq_str!($borrowed_ty, $owned_ty, str);
impl_partial_eq_str!($borrowed_ty, $owned_ty, &str);
impl_partial_eq_str!($borrowed_ty, $owned_ty, String);
impl_partial_eq_str!($borrowed_ty, $borrowed_ty, str);
impl_partial_eq_str!($borrowed_ty, $borrowed_ty, &str);
impl_partial_eq_str!($borrowed_ty, $borrowed_ty, String);
impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, str);
impl_partial_eq_str!($borrowed_ty, &$borrowed_ty, String);
};
}
impl_name_type!(GitRefNameBuf, GitRefName);
impl_name_type!(RefNameBuf, RefName);
impl_name_type!(RemoteNameBuf, RemoteName);
impl_name_type!(WorkspaceNameBuf, WorkspaceName);
impl RefName {
pub fn to_remote_symbol<'a>(&'a self, remote: &'a RemoteName) -> RemoteRefSymbol<'a> {
RemoteRefSymbol { name: self, remote }
}
}
impl WorkspaceName {
pub const DEFAULT: &Self = Self::new("default");
}
#[derive(Debug, RefCastCustom)]
#[repr(transparent)]
pub struct RefSymbol(str);
impl RefSymbol {
#[ref_cast_custom]
const fn new(name: &str) -> &Self;
}
impl Display for RefSymbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(&revset::format_symbol(&self.0))
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RemoteRefSymbolBuf {
pub name: RefNameBuf,
pub remote: RemoteNameBuf,
}
impl RemoteRefSymbolBuf {
pub fn as_ref(&self) -> RemoteRefSymbol<'_> {
RemoteRefSymbol {
name: &self.name,
remote: &self.remote,
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RemoteRefSymbol<'a> {
pub name: &'a RefName,
pub remote: &'a RemoteName,
}
impl RemoteRefSymbol<'_> {
pub fn to_owned(self) -> RemoteRefSymbolBuf {
RemoteRefSymbolBuf {
name: self.name.to_owned(),
remote: self.remote.to_owned(),
}
}
}
impl From<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
fn from(value: RemoteRefSymbol<'_>) -> Self {
value.to_owned()
}
}
impl PartialEq<RemoteRefSymbol<'_>> for RemoteRefSymbolBuf {
fn eq(&self, other: &RemoteRefSymbol) -> bool {
self.as_ref() == *other
}
}
impl PartialEq<RemoteRefSymbol<'_>> for &RemoteRefSymbolBuf {
fn eq(&self, other: &RemoteRefSymbol) -> bool {
self.as_ref() == *other
}
}
impl PartialEq<RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
fn eq(&self, other: &RemoteRefSymbolBuf) -> bool {
*self == other.as_ref()
}
}
impl PartialEq<&RemoteRefSymbolBuf> for RemoteRefSymbol<'_> {
fn eq(&self, other: &&RemoteRefSymbolBuf) -> bool {
*self == other.as_ref()
}
}
impl Display for RemoteRefSymbolBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.as_ref(), f)
}
}
impl Display for RemoteRefSymbol<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let RemoteRefSymbol { name, remote } = self;
f.pad(&revset::format_remote_symbol(&name.0, &remote.0))
}
}