use crate::*;
use core::cmp::Ordering;
impl_for! { Eq }
impl_for! {
<2> PartialEq<self2!()>:
#[inline]
fn eq(&self, other: &self2!()) -> bool {
match (SIZE == SIZE2, Self::FIXED, other.is_fixed(), Self::TRIM, other.is_trim()) {
(true, ..) => SIZE == 0 || self.str == other.str[..],
(_, true, true, ..) => false,
(_, true, _, _, true) => SIZE < SIZE2 && SIZE + 1 == SIZE2 && self.str == other.as_bytes(),
(_, _, true, true, _) => SIZE > SIZE2 && SIZE == SIZE2 + 1 && self.as_bytes() == other.str,
(_, true, ..) => SIZE < SIZE2 && self.str == other.as_bytes(),
(_, _, true, ..) => SIZE > SIZE2 && self.as_bytes() == other.str,
(.., true, _) => (SIZE < SIZE2 || SIZE == SIZE2 + 1) && self.as_bytes() == other.as_bytes(),
(.., true) => (SIZE > SIZE2 || SIZE + 1 == SIZE2) && self.as_bytes() == other.as_bytes(),
_ => self.as_bytes() == other.as_bytes(),
}
}
}
impl_for! {
<'a, 2> PartialEq<&'a self2!()>:
#[inline(always)]
fn eq(&self, other: &&'a self2!()) -> bool {
self.eq(*other)
}
}
impl_for! {
PartialEq<str>:
#[inline]
fn eq(&self, other: &str) -> bool {
if SIZE == 0 {
other.is_empty()
} else if Self::FIXED {
self.str == other.as_bytes()
} else {
self.as_bytes() == other.as_bytes()
}
}
}
impl_for! {
<'a> PartialEq<&'a str>:
#[inline(always)]
fn eq(&self, other: &&'a str) -> bool {
self.eq(*other)
}
}
impl_for! {
PartialEq<String>:
#[inline]
fn eq(&self, other: &String) -> bool {
self.eq(other.as_str())
}
}
impl_for! {
<2> PartialOrd<self2!()>:
fn partial_cmp(&self, other: &self2!()) -> Option<Ordering> {
Some(if Self::FIXED && other.is_fixed() {
self.str[..].cmp(&other.str[..])
} else if Self::FIXED {
self.str[..].cmp(other.as_bytes())
} else if other.is_fixed() {
self.as_bytes().cmp(&other.str[..])
} else {
self.as_bytes().cmp(other.as_bytes())
})
}
}
impl_for! {
<'a, 2> PartialOrd<&'a self2!()>:
fn partial_cmp(&self, other: &&'a self2!()) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl_for! {
PartialOrd<str>:
#[inline]
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
if Self::FIXED {
self.str[..].partial_cmp(other.as_bytes())
} else {
self.as_bytes().partial_cmp(other.as_bytes())
}
}
}
impl_for! {
<'a> PartialOrd<&'a str>:
#[inline(always)]
fn partial_cmp(&self, other: &&'a str) -> Option<Ordering> {
self.partial_cmp(*other)
}
}
impl_for! {
Ord:
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! cmp_all {
($op:tt) => {
cmp_all!($op:
stringlet!(""),
stringlet!(v: ""),
stringlet!(v 1: ""),
stringlet!(v 2: ""),
stringlet!(t: ""),
stringlet!(t 1: ""),
stringlet!(s: ""),
stringlet!(s 1: ""),
stringlet!(s 2: ""),
stringlet!("x"),
stringlet!(v: "x"),
stringlet!(v 2: "x"),
stringlet!(v 3: "x"),
stringlet!(t: "x"),
stringlet!(t 2: "x"),
stringlet!(s: "x"),
stringlet!(s 2: "x"),
stringlet!(s 3: "x"),
stringlet!("y"),
stringlet!(v: "y"),
stringlet!(v 2: "y"),
stringlet!(v 3: "y"),
stringlet!(t: "y"),
stringlet!(t 2: "y"),
stringlet!(s: "y"),
stringlet!(s 2: "y"),
stringlet!(s 3: "y"),
stringlet!("xy"),
stringlet!(v: "xy"),
stringlet!(v 3: "xy"),
stringlet!(v 4: "xy"),
stringlet!(t: "xy"),
stringlet!(t 3: "xy"),
stringlet!(s: "xy"),
stringlet!(s 3: "xy"),
stringlet!(s 4: "xy"),
);
};
($op:tt: $a:expr, $($rest:expr,)+) => {
let a = $a;
assert_eq!(a $op a.clone(), a.as_str() $op a.as_str(), "{a:#?}");
assert_eq!(a $op a.as_str(), a.as_str() $op a.as_str(), "{a:#?}");
let ac = const { $a };
assert_eq!(a $op ac, a.as_str() $op ac.as_str(), "{a:#?} {ac:#?}");
$(
let b = $rest;
assert_eq!(a $op b, a.as_str() $op b.as_str(), "{a:#?} {b:#?}");
assert_eq!(a $op b.as_str(), a.as_str() $op b.as_str(), "{a:#?} {b:#?}");
assert_eq!(b $op a, b.as_str() $op a.as_str(), "{a:#?} {b:#?}");
assert_eq!(b $op a.as_str(), b.as_str() $op a.as_str(), "{a:#?} {b:#?}");
)+
cmp_all!($op: $($rest,)+);
};
($op:tt: $a:expr,) => {};
}
#[test]
fn test_eq() {
cmp_all!(==);
}
#[test]
fn test_lt() {
cmp_all!(<);
}
#[test]
fn test_le() {
}
}