Skip to main content

updatehub_package_schema/definitions/
count.rs

1// Copyright (C) 2019 O.S. Systems Sofware LTDA
2//
3// SPDX-License-Identifier: Apache-2.0
4
5use serde::{Deserialize, Deserializer, de};
6
7/// How many `ChunkSize` blocks must be copied from the source file to
8/// the target. The default value of -1 means all possible bytes
9/// until the end of the file.
10#[derive(PartialEq, Eq, Debug, Clone, Default)]
11pub enum Count {
12    #[default]
13    All,
14    Limited(isize),
15}
16
17impl<'de> Deserialize<'de> for Count {
18    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
19    where
20        D: Deserializer<'de>,
21    {
22        match isize::deserialize(deserializer)? {
23            -1 => Ok(Count::All),
24            n if n >= 0 => Ok(Count::Limited(n)),
25            n => Err(de::Error::custom(format!("Invalid count: {n}"))),
26        }
27    }
28}
29
30impl std::iter::Iterator for Count {
31    type Item = isize;
32
33    fn next(&mut self) -> Option<Self::Item> {
34        match self {
35            Count::All => Some(0),
36            Count::Limited(n) => match n {
37                0 => None,
38                n => {
39                    *n -= 1;
40                    Some(*n)
41                }
42            },
43        }
44    }
45}
46
47#[cfg(test)]
48mod test {
49    use super::*;
50    use pretty_assertions::assert_eq;
51    use serde_json::json;
52
53    #[derive(Debug, PartialEq, Eq, Deserialize)]
54    struct Payload {
55        #[serde(default)]
56        count: Count,
57    }
58
59    #[test]
60    fn deserialize() {
61        assert_eq!(
62            serde_json::from_value::<Payload>(json!({ "count": 0 })).unwrap(),
63            Payload { count: Count::Limited(0) }
64        );
65    }
66
67    #[test]
68    fn default() {
69        assert_eq!(
70            serde_json::from_value::<Payload>(json!({})).unwrap(),
71            Payload { count: Count::All }
72        );
73    }
74
75    #[test]
76    fn validation_of_minimal() {
77        assert!(serde_json::from_value::<Payload>(json!({ "count": -2 })).is_err());
78    }
79}