use std::borrow::Cow;
pub(crate) fn decode_fixed_utf8(bytes: &[u8]) -> String {
decode_fixed_utf8_cow(bytes).into_owned()
}
pub(crate) fn decode_fixed_utf8_cow(bytes: &[u8]) -> Cow<'_, str> {
let len = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len());
String::from_utf8_lossy(&bytes[..len])
}
pub(crate) fn decode_fixed_ascii(bytes: &[u8]) -> String {
bytes.iter().take_while(|&&b| b != 0).map(|&b| if b < 0x80 { b as char } else { '?' }).collect()
}
pub(crate) fn truncate_utf16(s: &str, max_units: usize) -> Cow<'_, str> {
let mut units = 0;
for (i, c) in s.char_indices() {
let n = c.len_utf16();
if units + n > max_units {
if units < max_units {
let mut out = s[..i].to_owned();
out.push('\u{FFFD}');
return Cow::Owned(out);
}
return Cow::Borrowed(&s[..i]);
}
units += n;
}
Cow::Borrowed(s)
}
pub(crate) fn write_utf8_field(dest: &mut [u8], s: &str) -> crate::Result<()> {
if s.len() > dest.len() {
return Err(crate::Error::StringTooLong { max: dest.len(), actual: s.len() });
}
dest.fill(0);
dest[..s.len()].copy_from_slice(s.as_bytes());
Ok(())
}
pub(crate) fn write_ascii_field(dest: &mut [u8], s: &str) -> crate::Result<()> {
let len = s.encode_utf16().count();
if len > dest.len() {
return Err(crate::Error::StringTooLong { max: dest.len(), actual: len });
}
dest.fill(0);
for (d, unit) in dest.iter_mut().zip(s.encode_utf16()) {
*d = if unit < 0x80 { unit as u8 } else { b'?' };
}
Ok(())
}