use std::borrow::Cow;
use bstr::{BStr, BString, ByteSlice};
use gix_utils::git_is_space;
#[must_use]
pub fn normalize(input: &(impl crate::AsBStr + ?Sized)) -> Cow<'_, BStr> {
normalize_inner(input.as_bstr())
}
fn normalize_inner(input: &BStr) -> Cow<'_, BStr> {
if input.len() >= 2
&& input[0] == b'"'
&& input[input.len() - 1] == b'"'
&& input[1..input.len() - 1].find_byteset(br#"\""#).is_none()
{
return Cow::Borrowed(input[1..input.len() - 1].as_ref());
}
if input.find_byteset(br#"\""#).is_none() {
return Cow::Borrowed(input);
}
let mut out: BString = Vec::with_capacity(input.len()).into();
let mut bytes = input.iter().copied();
let mut is_in_quotes = false;
while let Some(c) = bytes.next() {
match c {
b'\\' => match bytes.next() {
Some(b'n') => out.push(b'\n'),
Some(b't') => out.push(b'\t'),
Some(b'b') => out.push(b'\x08'),
Some(c) => {
out.push(c);
}
None => break,
},
b'"' => is_in_quotes = !is_in_quotes,
c if !is_in_quotes && out.is_empty() && git_is_space(c) => {}
_ => out.push(c),
}
}
Cow::Owned(out)
}