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}
33impl NixDeserialize for i64 {
34    async fn try_deserialize<R>(reader: &mut R) -> Result<Option<Self>, R::Error>
35    where
36        R: ?Sized + NixRead + Send,
37    {
38        Ok(reader.try_read_number().await?.map(|v| v as i64))
39    }
40}
41
42#[cfg(test)]
43mod test {
44    use hex_literal::hex;
45    use rstest::rstest;
46    use tokio_test::io::Builder;
47
48    use crate::wire::de::{NixRead, NixReader};
49
50    #[rstest]
51    #[case::simple_false(false, &hex!("0000 0000 0000 0000"))]
52    #[case::simple_true(true, &hex!("0100 0000 0000 0000"))]
53    #[case::other_true(true, &hex!("1234 5600 0000 0000"))]
54    #[case::max_true(true, &hex!("FFFF FFFF FFFF FFFF"))]
55    #[tokio::test]
56    async fn test_read_bool(#[case] expected: bool, #[case] data: &[u8]) {
57        let mock = Builder::new().read(data).build();
58        let mut reader = NixReader::new(mock);
59        let actual: bool = reader.read_value().await.unwrap();
60        assert_eq!(actual, expected);
61    }
62
63    #[rstest]
64    #[case::zero(0, &hex!("0000 0000 0000 0000"))]
65    #[case::one(1, &hex!("0100 0000 0000 0000"))]
66    #[case::other(0x563412, &hex!("1234 5600 0000 0000"))]
67    #[case::max_value(u64::MAX, &hex!("FFFF FFFF FFFF FFFF"))]
68    #[tokio::test]
69    async fn test_read_u64(#[case] expected: u64, #[case] data: &[u8]) {
70        let mock = Builder::new().read(data).build();
71        let mut reader = NixReader::new(mock);
72        let actual: u64 = reader.read_value().await.unwrap();
73        assert_eq!(actual, expected);
74    }
75
76    #[rstest]
77    #[case::zero(0, &hex!("0000 0000 0000 0000"))]
78    #[case::one(1, &hex!("0100 0000 0000 0000"))]
79    #[case::other(0x563412, &hex!("1234 5600 0000 0000"))]
80    #[case::max_value(usize::MAX, &usize::MAX.to_le_bytes())]
81    #[tokio::test]
82    async fn test_read_usize(#[case] expected: usize, #[case] data: &[u8]) {
83        let mock = Builder::new().read(data).build();
84        let mut reader = NixReader::new(mock);
85        let actual: usize = reader.read_value().await.unwrap();
86        assert_eq!(actual, expected);
87    }
88
89    // FUTUREWORK: Test this on supported hardware
90    #[tokio::test]
91    #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
92    async fn test_read_usize_overflow() {
93        let mock = Builder::new().read(&u64::MAX.to_le_bytes()).build();
94        let mut reader = NixReader::new(mock);
95        assert_eq!(
96            std::io::ErrorKind::InvalidData,
97            reader.read_value::<usize>().await.unwrap_err().kind()
98        );
99    }
100}