Skip to main content

nix_compat/wire/de/
int.rs

1use super::{Error, NixDeserialize, NixRead};
2
3impl NixDeserialize for u64 {
4    async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
5    where
6        R: ?Sized + NixRead + Send,
7    {
8        reader.try_read_number().await
9    }
10}
11
12impl NixDeserialize for usize {
13    async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
14    where
15        R: ?Sized + NixRead + Send,
16    {
17        if let Some(value) = reader.try_read_number().await? {
18            value.try_into().map_err(R::Error::invalid_data).map(Some)
19        } else {
20            Ok(None)
21        }
22    }
23}
24
25impl NixDeserialize for bool {
26    async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
27    where
28        R: ?Sized + NixRead + Send,
29    {
30        Ok(reader.try_read_number().await?.map(|v| v != 0))
31    }
32}
33
34#[cfg(test)]
35mod test {
36    use hex_literal::hex;
37    use rstest::rstest;
38    use tokio_test::io::Builder;
39
40    use crate::wire::de::{NixRead, NixReader};
41
42    #[rstest]
43    #[case::simple_false(false, &hex!("0000 0000 0000 0000"))]
44    #[case::simple_true(true, &hex!("0100 0000 0000 0000"))]
45    #[case::other_true(true, &hex!("1234 5600 0000 0000"))]
46    #[case::max_true(true, &hex!("FFFF FFFF FFFF FFFF"))]
47    #[tokio::test]
48    async fn test_read_bool(#[case] expected: bool, #[case] data: &[u8]) {
49        let mock = Builder::new().read(data).build();
50        let mut reader = NixReader::new(mock);
51        let actual: bool = reader.read_value().await.unwrap();
52        assert_eq!(actual, expected);
53    }
54
55    #[rstest]
56    #[case::zero(0, &hex!("0000 0000 0000 0000"))]
57    #[case::one(1, &hex!("0100 0000 0000 0000"))]
58    #[case::other(0x563412, &hex!("1234 5600 0000 0000"))]
59    #[case::max_value(u64::MAX, &hex!("FFFF FFFF FFFF FFFF"))]
60    #[tokio::test]
61    async fn test_read_u64(#[case] expected: u64, #[case] data: &[u8]) {
62        let mock = Builder::new().read(data).build();
63        let mut reader = NixReader::new(mock);
64        let actual: u64 = reader.read_value().await.unwrap();
65        assert_eq!(actual, expected);
66    }
67
68    #[rstest]
69    #[case::zero(0, &hex!("0000 0000 0000 0000"))]
70    #[case::one(1, &hex!("0100 0000 0000 0000"))]
71    #[case::other(0x563412, &hex!("1234 5600 0000 0000"))]
72    #[case::max_value(usize::MAX, &usize::MAX.to_le_bytes())]
73    #[tokio::test]
74    async fn test_read_usize(#[case] expected: usize, #[case] data: &[u8]) {
75        let mock = Builder::new().read(data).build();
76        let mut reader = NixReader::new(mock);
77        let actual: usize = reader.read_value().await.unwrap();
78        assert_eq!(actual, expected);
79    }
80
81    // FUTUREWORK: Test this on supported hardware
82    #[tokio::test]
83    #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
84    async fn test_read_usize_overflow() {
85        let mock = Builder::new().read(&u64::MAX.to_le_bytes()).build();
86        let mut reader = NixReader::new(mock);
87        assert_eq!(
88            std::io::ErrorKind::InvalidData,
89            reader.read_value::<usize>().await.unwrap_err().kind()
90        );
91    }
92}