rtsc/
data_policy.rs

1use core::fmt;
2use std::{mem, str::FromStr};
3
4use crate::{Error, Result};
5
6/// Data delivery policies, used by [`crate::pdeque::Deque`]
7#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
8pub enum DeliveryPolicy {
9    #[default]
10    /// always deliver, fail if no room (default)
11    Always,
12    /// always deliver, drop the previous if no room (act as a ring-buffer)
13    Latest,
14    /// skip delivery if no room
15    Optional,
16    /// always deliver the frame but always in a single copy (latest)
17    Single,
18    /// deliver a single latest copy, skip if no room
19    SingleOptional,
20}
21
22impl FromStr for DeliveryPolicy {
23    type Err = Error;
24
25    fn from_str(s: &str) -> Result<Self> {
26        match s.to_lowercase().as_str() {
27            "always" => Ok(DeliveryPolicy::Always),
28            "optional" => Ok(DeliveryPolicy::Optional),
29            "single" => Ok(DeliveryPolicy::Single),
30            "single-optional" => Ok(DeliveryPolicy::SingleOptional),
31            _ => Err(Error::InvalidData(s.to_string())),
32        }
33    }
34}
35
36impl fmt::Display for DeliveryPolicy {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        write!(
39            f,
40            "{}",
41            match self {
42                DeliveryPolicy::Always => "always",
43                DeliveryPolicy::Latest => "latest",
44                DeliveryPolicy::Optional => "optional",
45                DeliveryPolicy::Single => "single",
46                DeliveryPolicy::SingleOptional => "single-optional",
47            }
48        )
49    }
50}
51
52/// Implements delivery policies for own data types
53pub trait DataDeliveryPolicy
54where
55    Self: Sized,
56{
57    /// Delivery policy, the default is [`DeliveryPolicy::Always`]
58    fn delivery_policy(&self) -> DeliveryPolicy {
59        DeliveryPolicy::Always
60    }
61    /// Priority, for ordered, lower is better, the default is 100
62    fn priority(&self) -> usize {
63        100
64    }
65    /// Has equal kind with other
66    ///
67    /// (default: check enum discriminant)
68    fn eq_kind(&self, other: &Self) -> bool {
69        mem::discriminant(self) == mem::discriminant(other)
70    }
71    /// If a frame expires during storing/delivering, it is not delivered
72    fn is_expired(&self) -> bool {
73        false
74    }
75    #[doc(hidden)]
76    fn is_delivery_policy_single(&self) -> bool {
77        let dp = self.delivery_policy();
78        dp == DeliveryPolicy::Single || dp == DeliveryPolicy::SingleOptional
79    }
80    #[doc(hidden)]
81    fn is_delivery_policy_optional(&self) -> bool {
82        let dp = self.delivery_policy();
83        dp == DeliveryPolicy::Optional || dp == DeliveryPolicy::SingleOptional
84    }
85}
86
87/// Result payload of try_push operation
88pub enum StorageTryPushOutput<T: Sized> {
89    /// the value is pushed
90    Pushed,
91    /// the value has been skipped
92    Skipped,
93    /// the value has been returned back, usually because the buffer is full
94    Full(T),
95}
96
97impl DataDeliveryPolicy for () {}
98impl DataDeliveryPolicy for usize {}
99impl DataDeliveryPolicy for String {}
100impl<T> DataDeliveryPolicy for Vec<T> {}