1use std::{ffi::CString, str};
2
3pub trait ToPicoStr {
6 fn into_pico_i8_string(self) -> Vec<i8>;
8}
9
10impl<'a> ToPicoStr for &'a str {
11 fn into_pico_i8_string(self) -> Vec<i8> {
12 CString::new(self)
13 .expect("invalid CString")
14 .into_bytes_with_nul()
15 .iter()
16 .map(|&x| x as i8)
17 .collect()
18 }
19}
20
21pub trait FromPicoStr {
24 #[allow(clippy::wrong_self_convention)]
26 fn from_pico_i8_string(self, buf_len: usize) -> String;
27}
28
29impl FromPicoStr for &[i8] {
30 fn from_pico_i8_string(self, buf_len: usize) -> String {
31 let serial_vec: Vec<u8> = self[..(buf_len - 1)].iter().map(|&x| x as u8).collect();
32
33 str::from_utf8(&serial_vec)
34 .expect("invalid utf8 string")
35 .trim_matches(char::from(0))
39 .to_string()
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn pico_strings() {
49 let s1 = "something here";
50 let ps = s1.into_pico_i8_string();
51
52 assert_eq!(
53 ps,
54 vec![115, 111, 109, 101, 116, 104, 105, 110, 103, 32, 104, 101, 114, 101, 0]
55 );
56
57 let s2 = ps.from_pico_i8_string(ps.len());
58 assert_eq!(s1, s2)
59 }
60
61 #[test]
62 fn pico_strings_ps5000a_bug() {
63 let s1 = "something here";
64 let ps = [s1.into_pico_i8_string(), vec![0; 200]].concat();
66 let s2 = ps.from_pico_i8_string(ps.len());
67 assert_eq!(s1, s2)
68 }
69}