Hello,
I am currently writing a formatted for a custom string formatter. In Rust, I was expecting to have lazy generator, and then calling to_string()
or equivalent to actually do the work, and do as few allocation as possible (ie each string generated by the generator would be appended directly into the final string).
pub trait TextFormatter {
fn bold(s: &str) -> String;
fn strike(s: &str) -> String;
fn normal(s: &str) -> String;
}
pub fn format<T:>(some_boolean: bool, my_vec: Vec<i32>, _formatter: T)
-> String
where T: TextFormatter,
{
let mut out: String = String::new();
out += &format!("Some boolean: {}\n", some_boolean);
out += &format!("A comma separated list with some formatting: {}\n",
my_vec.iter().map(|&value|
if value == 1 || value == 10 {
T::bold(&value.to_string())
} else if value <= 5 {
T::strike(&value.to_string())
} else {
T::normal(&value.to_string())
})
.collect::<Vec<String>>()
.join(", "));
out
}
pub struct MarkdownFormatter;
impl TextFormatter for MarkdownFormatter {
fn bold(s: &str) -> String {
format!("**{}**", s)
}
fn strike(s: &str) -> String {
format!("~~*{}*~~", s)
}
fn normal(s: &str) -> String {
format!("{}", s)
}
}
How can I remove most (all?) allocations? Ideally all methods of TextFormatter
(including converting the input as strings), I would not need to collect the comma separated list into a Vec
before calling format!
, and finally if the format function itself could be lazy, it could be perfect.
I can change the whole architecture, the only thing I want to keep is the trait TextFormatter
with the 3 functions, but their types can change.