You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

79 lines
1.8 KiB

use std::fmt;
use std::iter::Iterator;
use std::slice::Iter as SliceIter;
use std::str::Chars;
const MAX_DATA_LEN: usize = 2000;
pub trait Strippable {
type Item: fmt::Display;
type TypeIter: Iterator<Item = Self::Item>;
fn length(&self) -> usize;
fn iterator(&self) -> Self::TypeIter;
}
impl<'a> Strippable for &'a str {
type Item = char;
type TypeIter = Chars<'a>;
fn length(&self) -> usize {
self.len()
}
fn iterator(&self) -> Self::TypeIter {
self.chars()
}
}
impl<'a> Strippable for &'a Vec<u8> {
type Item = &'a u8;
type TypeIter = SliceIter<'a, u8>;
fn length(&self) -> usize {
self.len()
}
fn iterator(&self) -> Self::TypeIter {
self.iter()
}
}
pub struct Stripped<'inner, Inner: Strippable + 'inner>(pub &'inner Inner);
impl<'inner, Inner: Strippable + 'inner> Stripped<'inner, Inner> {
fn iter(&self) -> Inner::TypeIter {
self.0.iterator()
}
fn placeholder(&self) -> &'static str {
if self.0.length() >= MAX_DATA_LEN {
" <...>"
} else {
""
}
}
}
impl<'inner, Inner: Strippable + 'inner> fmt::Display for Stripped<'inner, Inner> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let placeholder = self.placeholder();
for c in self.iter().take(MAX_DATA_LEN - placeholder.len()) {
write!(f, "{}", c)?;
}
write!(f, "{}", placeholder)
}
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::*;
#[rstest]
#[case("abc", 3)]
#[case("abcde".repeat(50), MAX_DATA_LEN)]
fn test_strip(#[case] input: impl Into<String>, #[case] result_len: usize) {
let s = input.into();
assert_eq!(Stripped(&s.as_str()).to_string().len(), result_len);
}
}