#![allow(clippy::len_without_is_empty)]
#[cfg(feature = "serde_json")]
pub(crate) mod json;
#[cfg(feature = "serde_yaml")]
pub(crate) mod yaml;
pub trait RandomTrailer {
fn prepare_string_with_tag(&self, input: &mut String, tag: &str);
fn prepare_vec_with_tag(&self, input: &mut Vec<u8>, tag: &str);
#[must_use]
fn remove_trailer(&self, string_like: &mut impl StringLike, random_tag: &str) -> bool;
}
#[derive(Clone, Debug, Default)]
pub struct NoopRandomTrailer;
impl RandomTrailer for NoopRandomTrailer {
fn prepare_string_with_tag(&self, _input: &mut String, _tag: &str) {}
fn prepare_vec_with_tag(&self, _input: &mut Vec<u8>, _tag: &str) {}
fn remove_trailer(&self, _string_like: &mut impl StringLike, _random_tag: &str) -> bool {
false
}
}
pub struct InputPlusTrailer<SliceType>(pub SliceType);
pub trait StringLike: std::fmt::Debug {
fn len(&self) -> usize;
fn ends_with_string(&self, string: &str) -> bool;
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool;
fn truncate_to_bytes(&mut self, target_len: usize);
}
impl StringLike for &str {
fn len(&self) -> usize {
(*self).len()
}
fn ends_with_string(&self, string: &str) -> bool {
self.ends_with(string)
}
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool {
self.ends_with(s2) && self[0..self.len() - s2.len()].ends_with(s1)
}
fn truncate_to_bytes(&mut self, target_len: usize) {
*self = &self[..target_len];
}
}
impl StringLike for &[u8] {
fn len(&self) -> usize {
(*self).len()
}
fn ends_with_string(&self, string: &str) -> bool {
self.ends_with(string.as_bytes())
}
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool {
self.ends_with(s2.as_bytes()) && self[0..self.len() - s2.len()].ends_with(s1.as_bytes())
}
fn truncate_to_bytes(&mut self, target_len: usize) {
*self = &self[..target_len];
}
}
impl StringLike for String {
fn len(&self) -> usize {
self.len()
}
fn ends_with_string(&self, string: &str) -> bool {
self.ends_with(string)
}
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool {
self.ends_with(s2) && self[0..self.len() - s2.len()].ends_with(s1)
}
fn truncate_to_bytes(&mut self, target_len: usize) {
self.truncate(target_len);
}
}
impl StringLike for Vec<u8> {
fn len(&self) -> usize {
self.len()
}
fn ends_with_string(&self, string: &str) -> bool {
self.ends_with(string.as_bytes())
}
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool {
self.ends_with(s2.as_bytes()) && self[0..self.len() - s2.len()].ends_with(s1.as_bytes())
}
fn truncate_to_bytes(&mut self, target_len: usize) {
self.truncate(target_len);
}
}
#[cfg(test)]
impl StringLike for std::borrow::Cow<'_, str> {
fn len(&self) -> usize {
(**self).len()
}
fn ends_with_string(&self, string: &str) -> bool {
self.ends_with(string)
}
fn ends_with_2_strings(&self, s1: &str, s2: &str) -> bool {
self.ends_with(s2) && self[0..self.len() - s2.len()].ends_with(s1)
}
fn truncate_to_bytes(&mut self, target_len: usize) {
match self {
std::borrow::Cow::Borrowed(slice) => {
slice.truncate_to_bytes(target_len);
}
std::borrow::Cow::Owned(string) => {
string.truncate_to_bytes(target_len);
}
}
}
}