Skip to content

Commit 718fc2a

Browse files
author
Juliette Cordor
committed
add truncation wrappers
1 parent 2c34427 commit 718fc2a

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

src/lib.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,108 @@ cfg_if::cfg_if! {
4141
pub mod root;
4242
}
4343
}
44+
45+
/// Truncation helpers for truncating strings when formatting
46+
pub mod truncate {
47+
use std::fmt;
48+
49+
#[derive(Debug)]
50+
#[must_use]
51+
/// A wrapper that truncates its contents when used.
52+
///
53+
/// This should be used through the [`fmt::Display`] trait,
54+
/// in [`println!`] and other formatting circumstances
55+
///
56+
/// # Examples
57+
///
58+
/// ```rust
59+
/// # use quork::truncate::Truncate;
60+
/// let name = Truncate::new("Juliette Cordor", 8);
61+
///
62+
/// assert_eq!(name.to_string(), "Juliette")
63+
/// ```
64+
pub struct Truncate<T> {
65+
length: usize,
66+
data: T,
67+
suffix: Option<String>,
68+
}
69+
70+
impl<T> Truncate<T> {
71+
/// Construct a new [`Truncate`] from the provided data and length
72+
pub fn new(data: T, length: usize) -> Self {
73+
Self {
74+
length,
75+
data,
76+
suffix: None,
77+
}
78+
}
79+
80+
/// Add a suffix to the provided [`Truncate`], to print after the truncation
81+
///
82+
/// # Examples
83+
///
84+
/// ```rust
85+
/// # use quork::truncate::Truncate;
86+
/// let mut name = Truncate::new("Juliette Cordor", 8).with_suffix("...");
87+
///
88+
/// assert_eq!(name.to_string(), "Juliette...")
89+
/// ```
90+
pub fn with_suffix(self, suffix: impl fmt::Display) -> Self {
91+
Self {
92+
suffix: Some(suffix.to_string()),
93+
..self
94+
}
95+
}
96+
}
97+
98+
impl<T: fmt::Display> fmt::Display for Truncate<T> {
99+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100+
use fmt::Write;
101+
let mut truncator = TruncatedFormatter::new(f, self.length);
102+
103+
write!(truncator, "{}", self.data)?;
104+
105+
if let Some(ref suffix) = self.suffix {
106+
write!(f, "{suffix}")?;
107+
}
108+
109+
Ok(())
110+
}
111+
}
112+
113+
#[derive(Debug)]
114+
#[must_use]
115+
/// A wrapper over a writer that truncates the output to a certain length
116+
///
117+
/// Primarily intended to be used through the [`Truncate`] struct
118+
pub struct TruncatedFormatter<'a, T> {
119+
remaining: usize,
120+
writer: &'a mut T,
121+
}
122+
123+
impl<'a, T> TruncatedFormatter<'a, T> {
124+
/// Construct a new [`TruncatedFormatter`] from the provided writer and length
125+
pub fn new(writer: &'a mut T, length: usize) -> Self {
126+
Self {
127+
remaining: length,
128+
writer,
129+
}
130+
}
131+
}
132+
133+
impl<'a, T> fmt::Write for TruncatedFormatter<'a, T>
134+
where
135+
T: fmt::Write,
136+
{
137+
fn write_str(&mut self, s: &str) -> fmt::Result {
138+
if self.remaining < s.len() {
139+
self.writer.write_str(&s[0..self.remaining])?;
140+
self.remaining = 0;
141+
Ok(())
142+
} else {
143+
self.remaining -= s.len();
144+
self.writer.write_str(s)
145+
}
146+
}
147+
}
148+
}

0 commit comments

Comments
 (0)