// Copyright 2025-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! Comparison facilities for [`NString`].

use core::cmp::Ordering;
use nvec::NString;

#[cfg(feature = "alloc")]
use alloc::borrow::Cow;

#[cfg(feature = "alloc")]
use alloc::string::String;

#[cfg(feature = "std")]
use std::ffi::OsStr;

#[cfg(feature = "std")]
use std::path::{Path, PathBuf};

impl<const N: usize> Eq for NString<N> {}

impl<const N: usize> Ord for NString<N> {
	#[inline]
	fn cmp(&self, other: &Self) -> Ordering {
		Ord::cmp(&**self, &**other)
	}
}

#[cfg(feature = "alloc")]
impl<const N: usize> PartialEq<Cow<'_, str>> for NString<N> {
	#[inline]
	fn eq(&self, other: &Cow<'_, str>) -> bool {
		PartialEq::eq(&**self, other)
	}

	#[inline]
	fn ne(&self, other: &Cow<'_, str>) -> bool {
		PartialEq::ne(&**self, other)
	}
}

impl<const N: usize, const M: usize> PartialEq<NString<M>> for NString<N> {
	#[inline]
	fn eq(&self, other: &NString<M>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NString<M>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

#[cfg(feature = "std")]
impl<const N: usize> PartialEq<Path> for NString<N> {
	#[inline]
	fn eq(&self, other: &Path) -> bool {
		let this: &OsStr = self.as_ref();
		PartialEq::eq(this, other)
	}

	#[inline]
	fn ne(&self, other: &Path) -> bool {
		let this: &OsStr = self.as_ref();
		PartialEq::ne(this, other)
	}
}

#[cfg(feature = "std")]
impl<const N: usize> PartialEq<PathBuf> for NString<N> {
	#[inline]
	fn eq(&self, other: &PathBuf) -> bool {
		let this: &OsStr = self.as_ref();
		PartialEq::eq(this, other)
	}

	#[inline]
	fn ne(&self, other: &PathBuf) -> bool {
		let this: &OsStr = self.as_ref();
		PartialEq::ne(this, other)
	}
}

impl<const N: usize> PartialEq<str> for NString<N> {
	#[inline]
	fn eq(&self, other: &str) -> bool {
		PartialEq::eq(&**self, other)
	}

	#[inline]
	fn ne(&self, other: &str) -> bool {
		PartialEq::ne(&**self, other)
	}
}

impl<const N: usize> PartialEq<&str> for NString<N> {
	#[inline]
	fn eq(&self, other: &&str) -> bool {
		PartialEq::eq(&**self, *other)
	}

	#[inline]
	fn ne(&self, other: &&str) -> bool {
		PartialEq::ne(&**self, *other)
	}
}

#[cfg(feature = "alloc")]
impl<const N: usize> PartialEq<String> for NString<N> {
	#[inline]
	fn eq(&self, other: &String) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &String) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

impl<const N: usize, const M: usize> PartialOrd<NString<M>> for NString<N> {
	#[inline]
	fn partial_cmp(&self, other: &NString<M>) -> Option<Ordering> {
		PartialOrd::partial_cmp(&**self, &**other)
	}

	#[inline]
	fn lt(&self, other: &NString<M>) -> bool {
		PartialOrd::lt(&**self, &**other)
	}

	#[inline]
	fn le(&self, other: &NString<M>) -> bool {
		PartialOrd::le(&**self, &**other)
	}

	#[inline]
	fn gt(&self, other: &NString<M>) -> bool {
		PartialOrd::gt(&**self, &**other)
	}

	#[inline]
	fn ge(&self, other: &NString<M>) -> bool {
		PartialOrd::ge(&**self, &**other)
	}
}

#[cfg(feature = "alloc")]
impl<const N: usize> PartialEq<NString<N>> for Cow<'_, str> {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}

#[cfg(feature = "std")]
impl<const N: usize> PartialEq<NString<N>> for Path {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		let other: &OsStr = other.as_ref();
		PartialEq::eq(self, other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		let other: &OsStr = other.as_ref();
		PartialEq::ne(self, other)
	}
}

#[cfg(feature = "std")]
impl<const N: usize> PartialEq<NString<N>> for PathBuf {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		let other: &OsStr = other.as_ref();
		PartialEq::eq(self, other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		let other: &OsStr = other.as_ref();
		PartialEq::ne(self, other)
	}
}

impl<const N: usize> PartialEq<NString<N>> for str {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		PartialEq::eq(self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		PartialEq::ne(self, &**other)
	}
}

impl<const N: usize> PartialEq<NString<N>> for &str {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		PartialEq::eq(*self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		PartialEq::ne(*self, &**other)
	}
}

#[cfg(feature = "alloc")]
impl<const N: usize> PartialEq<NString<N>> for String {
	#[inline]
	fn eq(&self, other: &NString<N>) -> bool {
		PartialEq::eq(&**self, &**other)
	}

	#[inline]
	fn ne(&self, other: &NString<N>) -> bool {
		PartialEq::ne(&**self, &**other)
	}
}
