use core::str::Utf8Error;
use thiserror::Error;
#[derive(Debug, PartialEq, Eq, Clone, Error)]
pub enum StringError {
#[error("string is not null terminated")]
MissingNul(#[source] core::ffi::FromBytesUntilNulError),
#[error("string is not valid UTF-8")]
Utf8(#[source] Utf8Error),
}
pub fn parse_slice_as_string(bytes: &[u8]) -> Result<&str, StringError> {
let cstr = core::ffi::CStr::from_bytes_until_nul(bytes).map_err(StringError::MissingNul)?;
cstr.to_str().map_err(StringError::Utf8)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_slice_as_string() {
assert!(matches!(
parse_slice_as_string(&[]),
Err(StringError::MissingNul(_))
));
assert_eq!(parse_slice_as_string(&[0x00]), Ok(""));
assert!(matches!(
parse_slice_as_string(&[0xff, 0x00]),
Err(StringError::Utf8(_))
));
assert!(matches!(
parse_slice_as_string(b"hello"),
Err(StringError::MissingNul(_))
));
assert_eq!(parse_slice_as_string(b"hello\0"), Ok("hello"));
assert_eq!(parse_slice_as_string(b"hello\0\0"), Ok("hello"));
assert_eq!(parse_slice_as_string(b"hello\0foo"), Ok("hello"));
}
}