common/
utils.rs

1use std::io::{Error, ErrorKind, Result};
2
3static mut STATIC_STRINGS: Vec<String> = Vec::new();
4
5pub fn into_static_str(value: String) -> &'static str {
6    unsafe {
7        // Well, this is ugly but the current usage should be actually safe:
8        // 1) It's used only by cli.rs to generate static strings for clap attributes.
9        // 2) Values are never modified after being pushed to vector.
10        // 3) Vectors is only modified / accessed by a single thread.
11        STATIC_STRINGS.push(value);
12        STATIC_STRINGS
13            .last()
14            .expect("Expected at least one static string result")
15            .as_str()
16    }
17}
18
19pub fn str_from_utf8(data: &[u8]) -> Result<&str> {
20    match std::str::from_utf8(data) {
21        Ok(str) => Ok(str),
22        Err(error) => Err(Error::new(
23            ErrorKind::InvalidData,
24            format!(
25                "Value does not have UTF-8 encoding (offset {})",
26                error.valid_up_to()
27            ),
28        )),
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test] // Do not use test_case, this is expected to work only for a single thread.
37    fn into_static_str() {
38        let str_1 = super::into_static_str("a".into());
39        let str_2 = super::into_static_str("ab".into());
40        let str_3 = super::into_static_str("abc".into());
41
42        assert_eq!(str_1, "a");
43        assert_eq!(str_2, "ab");
44        assert_eq!(str_3, "abc");
45    }
46
47    mod str_from_utf8 {
48        use super::*;
49        use crate::testing::unpack_io_error;
50
51        #[test]
52        fn ok() {
53            assert_eq!(
54                str_from_utf8(&[b'a', b'b', b'c'][..]).map_err(unpack_io_error),
55                Ok("abc")
56            );
57        }
58
59        #[test]
60        fn err() {
61            assert_eq!(
62                str_from_utf8(&[0, 159, 146, 150][..]).map_err(unpack_io_error),
63                Err((
64                    ErrorKind::InvalidData,
65                    "Value does not have UTF-8 encoding (offset 1)".into()
66                ))
67            );
68        }
69    }
70}