Help to make code more consise when using Cow
⚓ Rust 📅 2025-10-10 👤 surdeus 👁️ 4I have the following code:
use std::borrow::Cow;
pub fn json_encode(orig: &str) -> Cow<'_, str> {
let mut chars = orig.char_indices();
let mut owned = false;
let mut res = String::new();
while let Some( (i,c) ) = chars.next() {
match c {
'"' => { res = orig[..i].to_string();
res.push_str("\\\""); owned = true;
break},
'\n' => { res = orig[..i].to_string();
res.push_str("\x5Cn"); owned = true;
break},
'\r' => { res = orig[..i].to_string();
res.push_str("\x5cr"); owned = true;
break},
'\t' => { res = orig[..i].to_string();
res.push_str("\x5ct"); owned = true;
break},
'\\' => { res = orig[..i].to_string();
res.push_str("\x5c\x5c"); owned = true;
break},
_ => () ,
}
}
if owned {
while let Some( (_,c) ) = chars.next() {
match c {
'"' => res.push_str("\\\""),
'\n' => res.push_str("\x5Cn"),
'\r' => res.push_str("\x5cr"),
'\t' => res.push_str("\x5ct"),
'\\' => res.push_str("\x5c\x5c"),
_ => res.push(c),
}
}
Cow::Owned(res)
} else {
Cow::Borrowed(orig)
}
}
fn main() {
let value = json_encode(r#"Hello " \ "
world!"#);
println!("{}", value);
let value = json_encode("Hello world!");
println!("{}", value);
}
It's working, however, I do not like that res string is created regardless if returned the borrowed or an owned value. I tried to declare it without an initialization, but I couldn't convince the compiler - it's okay in the borrowed case.
res = orig[..i].to_string(); looks like a boilerplate, and I couldn't figure out how to get rid of it.
Finally, since I know approximately a length of owned value, I would prefer to set it explicitly.
Any other improvements you could see?
4 posts - 3 participants
🏷️ Rust_feed