extern crate alloc;
use alloc::borrow::Cow;
use alloc::rc::Rc;
use alloc::sync::Arc;
use core::borrow::Borrow;
use core::cmp::Ordering;
use core::fmt;
use core::fmt::Display;
use core::fmt::Formatter;
use core::hash::Hash;
use core::hash::Hasher;
use core::iter::FusedIterator;
use core::ops::Deref;
use core::str::FromStr;
use core::str::Split;
use delegate::delegate;
use miette::Diagnostic;
use momo::momo;
use serde::Deserialize;
use serde::Deserializer;
use snafu::ensure;
use snafu::Backtrace;
use snafu::Snafu;
#[derive(Debug)]
#[repr(transparent)]
pub struct Acc {
name: str,
}
impl Acc {
pub fn ancestors(&self) -> impl Iterator<Item = &Self> + '_ {
Ancestors { next: Some(self) }
}
#[must_use]
pub fn leaf_name(&self) -> &Seg {
let leaf = self
.name
.rsplit_once(':')
.map_or(&self.name, |(_, leaf)| leaf);
unsafe {
Seg::from_unchecked(leaf)
}
}
#[must_use]
pub fn parent(&self) -> Option<&Self> {
self.name.rsplit_once(':').map(|(parent, _)| {
#[allow(unsafe_code)]
unsafe {
Self::from_unchecked(parent)
}
})
}
pub fn segments(&self) -> Segments<'_> {
Segments {
inner: self.name.split(':'),
}
}
}
impl Acc {
#[allow(unsafe_code)]
const unsafe fn from_unchecked(name: &str) -> &Self {
unsafe {
let name: *const _ = name;
let name = name as *const _;
&*name
}
}
}
impl AsRef<str> for Acc {
#[inline]
fn as_ref(&self) -> &str {
self.borrow()
}
}
impl AsRef<Self> for Acc {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl Borrow<str> for Acc {
#[inline]
fn borrow(&self) -> &str {
self
}
}
impl Deref for Acc {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.name
}
}
impl<'de> Deserialize<'de> for &'de Acc {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = <&'de str>::deserialize(deserializer)?;
s.try_into().map_err(serde::de::Error::custom)
}
}
impl Display for Acc {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad(&self.name)
}
}
impl Eq for Acc {}
impl From<&Acc> for Arc<Acc> {
fn from(value: &Acc) -> Self {
let raw = Arc::<str>::from(&value.name);
unsafe { Self::from_raw(Arc::into_raw(raw) as _) }
}
}
impl From<Account> for Arc<Acc> {
fn from(value: Account) -> Self {
let raw = Arc::<str>::from(value.name);
unsafe { Self::from_raw(Arc::into_raw(raw) as _) }
}
}
impl From<&Acc> for Box<Acc> {
fn from(value: &Acc) -> Self {
let raw = Box::<str>::from(&value.name);
unsafe { Self::from_raw(Box::into_raw(raw) as _) }
}
}
impl From<Account> for Box<Acc> {
fn from(value: Account) -> Self {
let raw = value.name.into_boxed_str();
unsafe { Self::from_raw(Box::into_raw(raw) as _) }
}
}
impl From<&Acc> for Rc<Acc> {
fn from(value: &Acc) -> Self {
let raw = Rc::<str>::from(&value.name);
unsafe { Self::from_raw(Rc::into_raw(raw) as _) }
}
}
impl From<Account> for Rc<Acc> {
fn from(value: Account) -> Self {
let raw = Rc::<str>::from(value.name);
unsafe { Self::from_raw(Rc::into_raw(raw) as _) }
}
}
impl Hash for Acc {
#[inline]
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.name.hash(state);
}
}
impl Ord for Acc {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.segments().cmp(other.segments())
}
}
impl PartialEq for Acc {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.cmp(other).is_eq()
}
}
impl PartialEq<&str> for Acc {
#[inline]
fn eq(&self, other: &&str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for &str {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for Cow<'_, Acc> {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for Cow<'_, str> {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for String {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for str {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Cow<'_, Self>> for Acc {
#[inline]
fn eq(&self, other: &Cow<'_, Self>) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Cow<'_, str>> for Acc {
#[inline]
fn eq(&self, other: &Cow<'_, str>) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<String> for Acc {
#[inline]
fn eq(&self, other: &String) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<str> for Acc {
#[inline]
fn eq(&self, other: &str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialOrd for Acc {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialOrd<&str> for Acc {
#[inline]
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl PartialOrd<Acc> for &str {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Acc> for Cow<'_, Acc> {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Acc> for Cow<'_, str> {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Acc> for String {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Acc> for str {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Cow<'_, Self>> for Acc {
fn partial_cmp(&self, other: &Cow<'_, Self>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Cow<'_, str>> for Acc {
fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<String> for Acc {
#[inline]
fn partial_cmp(&self, other: &String) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<str> for Acc {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
other.try_into().ok().map(|other| self.cmp(other))
}
}
impl ToOwned for Acc {
type Owned = Account;
fn to_owned(&self) -> Self::Owned {
Account {
name: self.name.to_owned(),
}
}
}
impl<'a> TryFrom<&'a Seg> for &'a Acc {
type Error = AccountError;
fn try_from(segment: &'a Seg) -> Result<Self, Self::Error> {
Self::try_from(&segment.inner)
}
}
impl<'a> TryFrom<&'a str> for &'a Acc {
type Error = AccountError;
fn try_from(name: &'a str) -> Result<Self, Self::Error> {
ensure!(is_valid_account_name(name), AccountSnafu { name });
Ok(
#[allow(unsafe_code)]
unsafe {
Acc::from_unchecked(name)
},
)
}
}
#[derive(Clone, Debug, Deserialize)]
#[repr(transparent)]
#[serde(try_from = "String")]
pub struct Account {
name: String,
}
impl Account {
#[momo]
pub fn join(self, segment: impl AsRef<Seg>) -> Self {
let mut this = self;
this.name.push(':');
this.name.push_str(segment.as_ref().as_ref());
this
}
}
impl AsRef<Acc> for Account {
#[inline]
fn as_ref(&self) -> &Acc {
self
}
}
impl AsRef<str> for Account {
#[inline]
fn as_ref(&self) -> &str {
self
}
}
impl Borrow<Acc> for Account {
#[inline]
fn borrow(&self) -> &Acc {
self
}
}
impl Deref for Account {
type Target = Acc;
#[inline]
fn deref(&self) -> &Self::Target {
#[allow(unsafe_code)]
unsafe {
Acc::from_unchecked(&self.name)
}
}
}
impl Display for Account {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl Eq for Account {}
impl From<&Acc> for Account {
#[inline]
fn from(acc: &Acc) -> Self {
acc.to_owned()
}
}
impl From<&Self> for Account {
#[inline]
fn from(value: &Self) -> Self {
value.clone()
}
}
impl FromStr for Account {
type Err = <Self as TryFrom<&'static str>>::Error;
#[inline]
fn from_str(name: &str) -> Result<Self, Self::Err> {
Self::try_from(name)
}
}
impl Hash for Account {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
impl Ord for Account {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
(**self).cmp(&**other)
}
}
impl PartialEq for Account {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.cmp(other).is_eq()
}
}
impl PartialEq<&Acc> for Account {
#[inline]
fn eq(&self, other: &&Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<&str> for Account {
#[inline]
fn eq(&self, other: &&str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Acc> for Account {
#[inline]
fn eq(&self, other: &Acc) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for &Acc {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for &str {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for Acc {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for Cow<'_, Acc> {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for Cow<'_, str> {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for String {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Account> for str {
#[inline]
fn eq(&self, other: &Account) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Cow<'_, Acc>> for Account {
#[inline]
fn eq(&self, other: &Cow<'_, Acc>) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<Cow<'_, str>> for Account {
#[inline]
fn eq(&self, other: &Cow<'_, str>) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<String> for Account {
#[inline]
fn eq(&self, other: &String) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialEq<str> for Account {
#[inline]
fn eq(&self, other: &str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialOrd for Account {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialOrd<&Acc> for Account {
#[inline]
fn partial_cmp(&self, other: &&Acc) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl PartialOrd<&str> for Account {
#[inline]
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl PartialOrd<Acc> for Account {
#[inline]
fn partial_cmp(&self, other: &Acc) -> Option<Ordering> {
(**self).partial_cmp(other)
}
}
impl PartialOrd<Account> for &Acc {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for &str {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for Acc {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for Cow<'_, Acc> {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for Cow<'_, str> {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for String {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Account> for str {
#[inline]
fn partial_cmp(&self, other: &Account) -> Option<Ordering> {
other.partial_cmp(self).map(Ordering::reverse)
}
}
impl PartialOrd<Cow<'_, Acc>> for Account {
fn partial_cmp(&self, other: &Cow<'_, Acc>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Cow<'_, str>> for Account {
fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<String> for Account {
#[inline]
fn partial_cmp(&self, other: &String) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<str> for Account {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
(**self).partial_cmp(other)
}
}
impl TryFrom<&str> for Account {
type Error = AccountError;
#[inline]
fn try_from(name: &str) -> Result<Self, Self::Error> {
<&Acc>::try_from(name).map(Self::from)
}
}
impl TryFrom<&Seg> for Account {
type Error = <Self as TryFrom<&'static str>>::Error;
fn try_from(segment: &Seg) -> Result<Self, Self::Error> {
Self::try_from(&segment.inner)
}
}
impl TryFrom<Segment> for Account {
type Error = <Self as TryFrom<String>>::Error;
fn try_from(segment: Segment) -> Result<Self, Self::Error> {
Self::try_from(segment.inner)
}
}
impl TryFrom<String> for Account {
type Error = <Self as TryFrom<&'static str>>::Error;
#[inline]
fn try_from(name: String) -> Result<Self, Self::Error> {
ensure!(is_valid_account_name(&name), AccountSnafu { name });
Ok(Self { name })
}
}
#[derive(Debug, Diagnostic, Snafu)]
#[snafu(display("invalid account: {name:?}"))]
pub struct AccountError {
name: String,
backtrace: Backtrace,
}
#[must_use]
struct Ancestors<'a> {
next: Option<&'a Acc>,
}
impl FusedIterator for Ancestors<'_> {}
impl<'a> Iterator for Ancestors<'a> {
type Item = &'a Acc;
fn next(&mut self) -> Option<Self::Item> {
let next = self.next?;
self.next = next.parent();
Some(next)
}
}
#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Seg {
inner: str,
}
impl Seg {
#[allow(unsafe_code)]
#[inline]
const unsafe fn from_unchecked(name: &str) -> &Self {
let name: *const _ = name;
let name = name as *const _;
unsafe {
&*name
}
}
}
impl AsRef<str> for Seg {
#[inline]
fn as_ref(&self) -> &str {
self.borrow()
}
}
impl AsRef<Self> for Seg {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl Borrow<str> for Seg {
#[inline]
fn borrow(&self) -> &str {
self
}
}
impl Deref for Seg {
type Target = str;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Display for Seg {
delegate! {
to self.inner {
#[allow(clippy::inline_always)]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result;
}
}
}
impl PartialEq<&str> for Seg {
#[inline]
fn eq(&self, other: &&str) -> bool {
self.eq(*other)
}
}
impl PartialEq<Cow<'_, Self>> for Seg {
#[inline]
fn eq(&self, other: &Cow<'_, Self>) -> bool {
self.eq(&**other)
}
}
impl PartialEq<Cow<'_, str>> for Seg {
#[inline]
fn eq(&self, other: &Cow<'_, str>) -> bool {
self.eq(&**other)
}
}
impl PartialEq<Seg> for &str {
#[inline]
fn eq(&self, other: &Seg) -> bool {
other.eq(self)
}
}
impl PartialEq<Seg> for Cow<'_, Seg> {
#[inline]
fn eq(&self, other: &Seg) -> bool {
other.eq(self)
}
}
impl PartialEq<Seg> for Cow<'_, str> {
#[inline]
fn eq(&self, other: &Seg) -> bool {
other.eq(self)
}
}
impl PartialEq<Seg> for String {
#[inline]
fn eq(&self, other: &Seg) -> bool {
other.eq(self)
}
}
impl PartialEq<Seg> for str {
#[inline]
fn eq(&self, other: &Seg) -> bool {
other.eq(self)
}
}
impl PartialEq<String> for Seg {
#[inline]
fn eq(&self, other: &String) -> bool {
self.eq(&**other)
}
}
impl PartialEq<str> for Seg {
#[inline]
fn eq(&self, other: &str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialOrd<Cow<'_, Self>> for Seg {
#[inline]
fn partial_cmp(&self, other: &Cow<'_, Self>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Cow<'_, str>> for Seg {
#[inline]
fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Seg> for &str {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Seg> for Cow<'_, Seg> {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Seg> for Cow<'_, str> {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Seg> for String {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Seg> for str {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<String> for Seg {
#[inline]
fn partial_cmp(&self, other: &String) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<&str> for Seg {
#[inline]
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl PartialOrd<str> for Seg {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
self.inner.partial_cmp(other)
}
}
impl ToOwned for Seg {
type Owned = Segment;
#[inline]
fn to_owned(&self) -> Self::Owned {
self.into()
}
}
impl<'s> TryFrom<&'s str> for &'s Seg {
type Error = SegmentError;
fn try_from(segment: &'s str) -> Result<Self, Self::Error> {
ensure!(is_valid_account_segment(segment), SegmentSnafu { segment });
Ok(
#[allow(unsafe_code)]
unsafe {
Seg::from_unchecked(segment)
},
)
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Segment {
inner: String,
}
impl AsRef<Seg> for Segment {
#[inline]
fn as_ref(&self) -> &Seg {
self.borrow()
}
}
impl AsRef<str> for Segment {
#[inline]
fn as_ref(&self) -> &str {
self
}
}
impl Borrow<Seg> for Segment {
#[inline]
fn borrow(&self) -> &Seg {
self
}
}
impl Deref for Segment {
type Target = Seg;
#[inline]
fn deref(&self) -> &Self::Target {
#[allow(unsafe_code)]
unsafe {
Self::Target::from_unchecked(&self.inner)
}
}
}
impl Display for Segment {
delegate! {
to self.inner {
#[allow(clippy::inline_always)]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result;
}
}
}
impl From<&Seg> for Segment {
#[inline]
fn from(seg: &Seg) -> Self {
let inner = seg.inner.into();
Self { inner }
}
}
impl PartialEq<&str> for Segment {
#[inline]
fn eq(&self, other: &&str) -> bool {
self.eq(*other)
}
}
impl PartialEq<Cow<'_, Seg>> for Segment {
#[inline]
fn eq(&self, other: &Cow<'_, Seg>) -> bool {
self.eq(&**other)
}
}
impl PartialEq<Cow<'_, str>> for Segment {
#[inline]
fn eq(&self, other: &Cow<'_, str>) -> bool {
self.eq(&**other)
}
}
impl PartialEq<Seg> for Segment {
#[inline]
fn eq(&self, other: &Seg) -> bool {
(**self).eq(other)
}
}
impl PartialEq<Segment> for &str {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<Segment> for Cow<'_, Seg> {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<Segment> for Cow<'_, str> {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<Segment> for Seg {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<Segment> for String {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<Segment> for str {
#[inline]
fn eq(&self, other: &Segment) -> bool {
other.eq(self)
}
}
impl PartialEq<String> for Segment {
#[inline]
fn eq(&self, other: &String) -> bool {
self.eq(&**other)
}
}
impl PartialEq<str> for Segment {
#[inline]
fn eq(&self, other: &str) -> bool {
self.partial_cmp(other).map_or(false, Ordering::is_eq)
}
}
impl PartialOrd<Cow<'_, Seg>> for Segment {
#[inline]
fn partial_cmp(&self, other: &Cow<'_, Seg>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Cow<'_, str>> for Segment {
#[inline]
fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<Seg> for Segment {
#[inline]
fn partial_cmp(&self, other: &Seg) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for &str {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for Cow<'_, Seg> {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for Cow<'_, str> {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for Seg {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for String {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<Segment> for str {
#[inline]
fn partial_cmp(&self, other: &Segment) -> Option<Ordering> {
other.partial_cmp(self)
}
}
impl PartialOrd<String> for Segment {
#[inline]
fn partial_cmp(&self, other: &String) -> Option<Ordering> {
self.partial_cmp(&**other)
}
}
impl PartialOrd<&str> for Segment {
#[inline]
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl PartialOrd<str> for Segment {
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
(*self.inner).partial_cmp(other)
}
}
impl TryFrom<&str> for Segment {
type Error = <&'static Seg as TryFrom<&'static str>>::Error;
#[inline]
fn try_from(name: &str) -> Result<Self, Self::Error> {
<&Seg>::try_from(name).map(Self::from)
}
}
impl TryFrom<String> for Segment {
type Error = <Self as TryFrom<&'static str>>::Error;
#[inline]
fn try_from(segment: String) -> Result<Self, Self::Error> {
ensure!(is_valid_account_segment(&segment), SegmentSnafu { segment });
Ok(Self { inner: segment })
}
}
#[derive(Debug, Diagnostic, Snafu)]
#[snafu(display("invalid account segment: {segment:?}"))]
pub struct SegmentError {
segment: String,
backtrace: Backtrace,
}
#[derive(Clone, Debug)]
#[must_use]
pub struct Segments<'a> {
inner: Split<'a, char>,
}
impl DoubleEndedIterator for Segments<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|seg| {
#[allow(unsafe_code)]
unsafe {
Seg::from_unchecked(seg)
}
})
}
}
impl FusedIterator for Segments<'_> {}
impl<'a> Iterator for Segments<'a> {
type Item = &'a Seg;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|seg| {
#[allow(unsafe_code)]
unsafe {
Seg::from_unchecked(seg)
}
})
}
}
fn is_valid_account_name(name: &str) -> bool {
lazy_regex::regex_is_match!(
r#"^(?:[\p{Lu}\p{Nd}][-\p{L}\p{Nd}]*)(?::[\p{Lu}\p{Nd}][-\p{L}\p{Nd}]*)*$"#,
name
)
}
fn is_valid_account_segment(name: &str) -> bool {
lazy_regex::regex_is_match!(r#"^(?:[\p{Lu}\p{Nd}][-\p{L}\p{Nd}]*)$"#, name)
}