Line data Source code
1 : //! Small parsing helpers.
2 :
3 : use std::ffi::CStr;
4 :
5 69 : pub fn split_cstr(bytes: &[u8]) -> Option<(&CStr, &[u8])> {
6 69 : let cstr = CStr::from_bytes_until_nul(bytes).ok()?;
7 65 : let (_, other) = bytes.split_at(cstr.to_bytes_with_nul().len());
8 65 : Some((cstr, other))
9 69 : }
10 :
11 : /// See <https://doc.rust-lang.org/std/primitive.slice.html#method.split_array_ref>.
12 67 : pub fn split_at_const<const N: usize>(bytes: &[u8]) -> Option<(&[u8; N], &[u8])> {
13 67 : (bytes.len() >= N).then(|| {
14 65 : let (head, tail) = bytes.split_at(N);
15 65 : (head.try_into().unwrap(), tail)
16 67 : })
17 67 : }
18 :
19 : #[cfg(test)]
20 : mod tests {
21 : use super::*;
22 :
23 2 : #[test]
24 2 : fn test_split_cstr() {
25 2 : assert!(split_cstr(b"").is_none());
26 2 : assert!(split_cstr(b"foo").is_none());
27 :
28 2 : let (cstr, rest) = split_cstr(b"\0").expect("uh-oh");
29 2 : assert_eq!(cstr.to_bytes(), b"");
30 2 : assert_eq!(rest, b"");
31 :
32 2 : let (cstr, rest) = split_cstr(b"foo\0bar").expect("uh-oh");
33 2 : assert_eq!(cstr.to_bytes(), b"foo");
34 2 : assert_eq!(rest, b"bar");
35 2 : }
36 :
37 2 : #[test]
38 2 : fn test_split_at_const() {
39 2 : assert!(split_at_const::<0>(b"").is_some());
40 2 : assert!(split_at_const::<1>(b"").is_none());
41 2 : assert!(matches!(split_at_const::<1>(b"ok"), Some((b"o", b"k"))));
42 2 : }
43 : }
|