#![doc(issue_tracker_base_url = "https://github.com/MidasLamb/non-empty-string/issues/")]
#[cfg(doctest)]
mod test_readme {
#[doc = include_str!("../README.md")]
mod something {}
}
use delegate::delegate;
use std::fmt::Display;
#[cfg(feature = "serde")]
mod serde_support;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct NonEmptyString(String);
#[allow(clippy::len_without_is_empty)] impl NonEmptyString {
pub fn new(string: String) -> Result<NonEmptyString, String> {
if string.is_empty() {
Err(string)
} else {
Ok(NonEmptyString(string))
}
}
pub fn get(&self) -> &str {
&self.0
}
pub fn into_inner(self) -> String {
self.0
}
delegate! {
to self.0 {
pub fn into_bytes(self) -> Vec<u8>;
pub fn as_str(&self) -> &str;
pub fn push_str(&mut self, string: &str);
pub fn capacity(&self) -> usize;
pub fn reserve(&mut self, additional: usize);
pub fn reserve_exact(&mut self, additional: usize);
pub fn try_reserve_exact(
&mut self,
additional: usize
) -> Result<(), std::collections::TryReserveError>;
pub fn shrink_to_fit(&mut self);
pub fn shrink_to(&mut self, min_capacity: usize);
pub fn push(&mut self, ch: char);
pub fn as_bytes(&self) -> &[u8];
pub fn insert(&mut self, idx: usize, ch: char);
pub fn insert_str(&mut self, idx: usize, string: &str);
pub fn len(&self) -> usize;
pub fn into_boxed_str(self) -> Box<str>;
}
}
}
impl AsRef<str> for NonEmptyString {
fn as_ref(&self) -> &str {
&self.0
}
}
impl AsRef<String> for NonEmptyString {
fn as_ref(&self) -> &String {
&self.0
}
}
impl<'s> TryFrom<&'s str> for NonEmptyString {
type Error = &'s str;
fn try_from(value: &'s str) -> Result<Self, Self::Error> {
if value.is_empty() {
return Err(value);
}
Ok(NonEmptyString(value.to_owned()))
}
}
impl TryFrom<String> for NonEmptyString {
type Error = String;
fn try_from(value: String) -> Result<Self, Self::Error> {
NonEmptyString::new(value)
}
}
impl Display for NonEmptyString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.0, f)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_string_returns_err() {
assert_eq!(NonEmptyString::new("".to_owned()), Err("".to_owned()));
}
#[test]
fn non_empty_string_returns_ok() {
assert!(NonEmptyString::new("string".to_owned()).is_ok())
}
#[test]
fn what_goes_in_comes_out() {
assert_eq!(
NonEmptyString::new("string".to_owned())
.unwrap()
.into_inner(),
"string".to_owned()
);
}
#[test]
fn as_ref_str_works() {
let nes = NonEmptyString::new("string".to_owned()).unwrap();
let val: &str = nes.as_ref();
assert_eq!(val, "string");
}
#[test]
fn as_ref_string_works() {
let nes = NonEmptyString::new("string".to_owned()).unwrap();
let val: &String = nes.as_ref();
assert_eq!(val, "string");
}
#[test]
fn calling_string_methods_works() {
let nes = NonEmptyString::new("string".to_owned()).unwrap();
assert!(nes.len() > 0);
}
#[test]
fn format_test() {
let str = NonEmptyString::new("string".to_owned()).unwrap();
println!("{}", &str);
assert_eq!(String::from("string"), str.to_string())
}
}