use std::borrow::{Borrow, Cow};
use std::fmt::{self as stdfmt, Debug, Display};
use std::ops::Deref;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Kstr<'a> {
pub inner: Cow<'a, str>,
}
impl<'a> Kstr<'a> {
pub const fn brwed(s: &'a str) -> Self {
Self {
inner: Cow::Borrowed(s),
}
}
pub const fn owned(s: String) -> Kstr<'static> {
Kstr {
inner: Cow::Owned(s),
}
}
pub fn as_str(&self) -> &str {
&self.inner
}
pub fn to_mut(&mut self) -> &mut String {
self.inner.to_mut()
}
pub fn into_owned(self) -> Kstr<'static> {
Kstr::owned(self.inner.into_owned())
}
}
impl<'a> Deref for Kstr<'a> {
type Target = str;
fn deref(&self) -> &str {
&self.inner
}
}
impl<'a> AsRef<str> for Kstr<'a> {
fn as_ref(&self) -> &str {
&*self
}
}
impl<'a> Borrow<str> for Kstr<'a> {
fn borrow(&self) -> &str {
self.as_ref()
}
}
impl<'a> From<&'a str> for Kstr<'a> {
fn from(s: &'a str) -> Self {
Self::brwed(s)
}
}
impl From<String> for Kstr<'static> {
fn from(s: String) -> Self {
Self::owned(s)
}
}
impl<'a> Display for Kstr<'a> {
fn fmt(&self, f: &mut stdfmt::Formatter<'_>) -> stdfmt::Result {
write!(f, "{}", self.inner)
}
}
impl<'a> Debug for Kstr<'a> {
fn fmt(&self, f: &mut stdfmt::Formatter<'_>) -> stdfmt::Result {
write!(f, "{:?}", &self.inner)
}
}
impl<'a> PartialEq<str> for Kstr<'a> {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_eq() {
let one: Kstr = String::from("Hello, world").into();
let two: Kstr = "Hello, world".into();
assert_eq!(one, two);
}
#[test]
fn test_hash() {
let mut set = std::collections::HashSet::new();
set.insert(Kstr::owned("Hello, world!".to_owned()));
let two = Kstr::brwed("Hello, world!");
assert_eq!(set.contains(&two), true);
}
#[test]
fn to_mut_test() {
let mut kstr = Kstr::brwed("Hello");
assert_eq!(&kstr, "Hello");
kstr.to_mut().push_str(", world!");
assert_eq!(&kstr, "Hello, world!");
}
#[test]
fn as_ref_test() {
let kstr = Kstr::brwed("Hello, world!");
assert_eq!(kstr.as_ref(), "Hello, world!");
}
#[test]
fn display_test() {
let kstr = Kstr::brwed("Hello, world!");
assert_eq!(&kstr.to_string(), "Hello, world!");
}
#[test]
fn test_borrow_trait() {
let set = vec![Kstr::from("Hello"), Kstr::from("World")]
.into_iter()
.collect::<std::collections::HashSet<_>>();
assert_eq!(set.contains("Hello"), true);
assert_eq!(set.contains("World"), true);
assert_eq!(set.contains("rust"), false);
}
}