Skip to main content

made_core/value_objects/delivery/
queue_limit.rs

1use std::fmt;
2
3use serde::{Deserialize, Deserializer, Serialize};
4
5use crate::error::DomainError;
6
7const MIN: u32 = 1;
8const MAX: u32 = 1_000;
9const DEFAULT: u32 = 200;
10
11/// How many undelivered items one destination may hold before the
12/// oldest non-blocking one is dropped.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
14#[serde(transparent)]
15pub struct QueueLimit(u32);
16
17impl QueueLimit {
18    /// Construct a validated limit.
19    pub fn new(value: u32) -> Result<Self, DomainError> {
20        if !(MIN..=MAX).contains(&value) {
21            return Err(DomainError::OutOfRange {
22                field: "queue_limit",
23                value: f64::from(value),
24                min: f64::from(MIN),
25                max: f64::from(MAX),
26            });
27        }
28        Ok(Self(value))
29    }
30
31    #[must_use]
32    pub const fn value(self) -> u32 {
33        self.0
34    }
35}
36
37impl Default for QueueLimit {
38    fn default() -> Self {
39        Self(DEFAULT)
40    }
41}
42
43impl fmt::Display for QueueLimit {
44    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(formatter, "{}", self.0)
46    }
47}
48
49impl<'de> Deserialize<'de> for QueueLimit {
50    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51    where
52        D: Deserializer<'de>,
53    {
54        Self::new(u32::deserialize(deserializer)?).map_err(serde::de::Error::custom)
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn the_default_is_two_hundred_and_the_ceiling_is_a_thousand() {
64        assert_eq!(QueueLimit::default().value(), 200);
65        assert!(QueueLimit::new(0).is_err());
66        assert!(QueueLimit::new(1_001).is_err());
67    }
68}