#![allow(dead_code)]
use core::fmt;
use flexstr::{FlexStr, RefCounted, StringLike};
use flexstr_support::StringToFromBytes;
use inline_flexstr::{INLINE_CAPACITY, InlineFlexStr, TooLongForInlining};
pub fn test_empty_string<S, R>(empty: &'static S)
where
S: ?Sized + StringToFromBytes + PartialEq + fmt::Debug,
R: RefCounted<S> + fmt::Debug,
FlexStr<'static, S, R>: StringLike<S>,
Box<S>: From<S::Owned>,
S::Owned: AsRef<S>,
{
let flex_str: FlexStr<'_, S, R> = FlexStr::from_borrowed(empty);
assert!(StringLike::is_empty(&flex_str));
assert_eq!(StringLike::len(&flex_str), 0);
assert!(flex_str.is_borrowed());
let cloned = flex_str.clone();
assert_eq!(flex_str, cloned);
let owned = flex_str.to_owned();
assert_eq!(owned.as_ref_type(), empty);
assert!(StringLike::is_empty(&owned));
}
pub fn test_capacity_boundary_exact<S, R>(s: &'static S)
where
S: ?Sized + StringToFromBytes + fmt::Debug + PartialEq,
R: RefCounted<S>,
{
let bytes = s.self_as_raw_bytes();
assert_eq!(
bytes.len(),
INLINE_CAPACITY,
"test input must be exactly at capacity"
);
let inline_str =
InlineFlexStr::try_from_type(s).expect("string at exact capacity should inline");
let flex_str: FlexStr<'_, S, R> = FlexStr::from_inline(inline_str);
assert!(flex_str.is_inlined());
assert_eq!(flex_str.as_ref_type(), s);
}
pub fn test_capacity_boundary_overflow<S>(s: &'static S)
where
S: ?Sized + StringToFromBytes + fmt::Debug + PartialEq,
{
let bytes = s.self_as_raw_bytes();
assert!(
bytes.len() < INLINE_CAPACITY,
"test input must be smaller than capacity"
);
let _inline_str =
InlineFlexStr::try_from_type(s).expect("string smaller than capacity should succeed");
}
#[allow(unused)]
pub fn test_try_from_too_long() {
let _long_bytes = [0u8; INLINE_CAPACITY + 1];
let err = TooLongForInlining {
length: INLINE_CAPACITY + 1,
inline_capacity: INLINE_CAPACITY,
};
assert_eq!(err.length, INLINE_CAPACITY + 1);
assert_eq!(err.inline_capacity, INLINE_CAPACITY);
}
pub fn test_various_lengths<S, R>(s: &'static S)
where
S: ?Sized + StringToFromBytes + PartialEq + fmt::Debug,
R: RefCounted<S>,
FlexStr<'static, S, R>: StringLike<S>,
{
let bytes = s.self_as_bytes();
let len = bytes.len();
let flex_str: FlexStr<'_, S, R> = FlexStr::from_borrowed(s);
assert_eq!(StringLike::len(&flex_str), len);
assert_eq!(StringLike::is_empty(&flex_str), len == 0);
assert!(flex_str.is_borrowed());
let owned = flex_str.to_owned();
assert_eq!(StringLike::len(&owned), len);
assert_eq!(owned.as_ref_type(), s);
}
pub fn test_special_content<S, R>(s: &'static S)
where
S: ?Sized + StringToFromBytes + PartialEq,
R: RefCounted<S>,
{
let flex_str: FlexStr<'_, S, R> = FlexStr::from_borrowed(s);
let bytes = flex_str.as_bytes();
assert_eq!(bytes, s.self_as_bytes());
let raw_bytes = flex_str.as_raw_bytes();
assert_eq!(raw_bytes, s.self_as_raw_bytes());
let owned = flex_str.to_owned();
assert_eq!(owned.as_bytes(), bytes);
assert_eq!(owned.as_raw_bytes(), raw_bytes);
}
pub fn test_clone_variants<S, R>(s: &'static S)
where
S: ?Sized + StringToFromBytes + PartialEq + fmt::Debug,
R: RefCounted<S> + fmt::Debug,
Box<S>: From<S::Owned>,
S::Owned: AsRef<S>,
{
let borrowed: FlexStr<'_, S, R> = FlexStr::from_borrowed(s);
let cloned = borrowed.clone();
assert_eq!(borrowed, cloned);
let inline_str =
InlineFlexStr::try_from_type(s).expect("test input should be small enough to inline");
let inlined: FlexStr<'_, S, R> = FlexStr::from_inline(inline_str);
let cloned = inlined.clone();
assert_eq!(inlined, cloned);
let rc: R = s.into();
let ref_counted: FlexStr<'_, S, R> = FlexStr::from_ref_counted(rc.clone());
let cloned = ref_counted.clone();
assert_eq!(ref_counted, cloned);
let boxed: FlexStr<'_, S, R> = FlexStr::from_boxed(Box::from(s.to_owned()));
let cloned = boxed.clone();
assert!(matches!(
cloned,
FlexStr::Inlined(_) | FlexStr::RefCounted(_)
));
assert_eq!(boxed, cloned);
}