canlink_hal/queue/
config.rs1use std::time::Duration;
6
7use serde::Deserialize;
8
9use super::{BoundedQueue, QueueOverflowPolicy};
10
11#[derive(Debug, Clone, Deserialize)]
34pub struct QueueConfig {
35 #[serde(default = "default_capacity")]
37 pub capacity: usize,
38
39 #[serde(default)]
41 pub overflow_policy: OverflowPolicyConfig,
42}
43
44fn default_capacity() -> usize {
45 super::bounded::DEFAULT_QUEUE_CAPACITY
46}
47
48impl Default for QueueConfig {
49 fn default() -> Self {
50 Self {
51 capacity: default_capacity(),
52 overflow_policy: OverflowPolicyConfig::default(),
53 }
54 }
55}
56
57#[derive(Debug, Clone, Deserialize)]
59#[serde(tag = "type", rename_all = "snake_case")]
60#[derive(Default)]
61pub enum OverflowPolicyConfig {
62 #[default]
64 DropOldest,
65 DropNewest,
67 Block {
69 #[serde(default = "default_timeout_ms")]
71 timeout_ms: u64,
72 },
73}
74
75fn default_timeout_ms() -> u64 {
76 100
77}
78
79impl From<OverflowPolicyConfig> for QueueOverflowPolicy {
80 fn from(config: OverflowPolicyConfig) -> Self {
81 match config {
82 OverflowPolicyConfig::DropOldest => QueueOverflowPolicy::DropOldest,
83 OverflowPolicyConfig::DropNewest => QueueOverflowPolicy::DropNewest,
84 OverflowPolicyConfig::Block { timeout_ms } => QueueOverflowPolicy::Block {
85 timeout: Duration::from_millis(timeout_ms),
86 },
87 }
88 }
89}
90
91impl QueueConfig {
92 #[must_use]
94 pub fn into_queue(self) -> BoundedQueue {
95 BoundedQueue::with_policy(self.capacity, self.overflow_policy.into())
96 }
97
98 pub fn from_toml(toml_str: &str) -> Result<Self, toml::de::Error> {
105 toml::from_str(toml_str)
106 }
107}
108
109impl BoundedQueue {
110 #[must_use]
112 pub fn from_config(config: &QueueConfig) -> Self {
113 BoundedQueue::with_policy(config.capacity, config.overflow_policy.clone().into())
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_default_config() {
123 let config = QueueConfig::default();
124 assert_eq!(config.capacity, 1000);
125 assert!(matches!(
126 config.overflow_policy,
127 OverflowPolicyConfig::DropOldest
128 ));
129 }
130
131 #[test]
132 fn test_parse_drop_oldest() {
133 let toml = r#"
134 capacity = 500
135 [overflow_policy]
136 type = "drop_oldest"
137 "#;
138
139 let config: QueueConfig = toml::from_str(toml).unwrap();
140 assert_eq!(config.capacity, 500);
141 assert!(matches!(
142 config.overflow_policy,
143 OverflowPolicyConfig::DropOldest
144 ));
145 }
146
147 #[test]
148 fn test_parse_drop_newest() {
149 let toml = r#"
150 capacity = 200
151 [overflow_policy]
152 type = "drop_newest"
153 "#;
154
155 let config: QueueConfig = toml::from_str(toml).unwrap();
156 assert_eq!(config.capacity, 200);
157 assert!(matches!(
158 config.overflow_policy,
159 OverflowPolicyConfig::DropNewest
160 ));
161 }
162
163 #[test]
164 fn test_parse_block() {
165 let toml = r#"
166 capacity = 100
167 [overflow_policy]
168 type = "block"
169 timeout_ms = 250
170 "#;
171
172 let config: QueueConfig = toml::from_str(toml).unwrap();
173 assert_eq!(config.capacity, 100);
174 match config.overflow_policy {
175 OverflowPolicyConfig::Block { timeout_ms } => {
176 assert_eq!(timeout_ms, 250);
177 }
178 _ => panic!("Expected Block policy"),
179 }
180 }
181
182 #[test]
183 fn test_into_queue() {
184 let config = QueueConfig {
185 capacity: 50,
186 overflow_policy: OverflowPolicyConfig::DropNewest,
187 };
188
189 let queue = config.into_queue();
190 assert_eq!(queue.capacity(), 50);
191 assert!(matches!(queue.policy(), QueueOverflowPolicy::DropNewest));
192 }
193
194 #[test]
195 fn test_policy_conversion() {
196 let policy: QueueOverflowPolicy = OverflowPolicyConfig::DropOldest.into();
197 assert!(matches!(policy, QueueOverflowPolicy::DropOldest));
198
199 let policy: QueueOverflowPolicy = OverflowPolicyConfig::DropNewest.into();
200 assert!(matches!(policy, QueueOverflowPolicy::DropNewest));
201
202 let policy: QueueOverflowPolicy = OverflowPolicyConfig::Block { timeout_ms: 100 }.into();
203 assert!(matches!(policy, QueueOverflowPolicy::Block { .. }));
204 assert_eq!(policy.timeout(), Some(Duration::from_millis(100)));
205 }
206}