1use core::fmt;
6
7#[cfg(not(feature = "std"))]
8extern crate alloc;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub enum BufferCfg {
30 SpmcRing {
37 capacity: usize,
39 },
40
41 SingleLatest,
46
47 Mailbox,
52}
53
54impl BufferCfg {
55 pub fn validate(&self) -> Result<(), &'static str> {
59 match self {
60 BufferCfg::SpmcRing { capacity } => {
61 if *capacity == 0 {
62 return Err("SPMC ring capacity must be > 0");
63 }
64 Ok(())
67 }
68 BufferCfg::SingleLatest | BufferCfg::Mailbox => Ok(()),
69 }
70 }
71
72 pub fn name(&self) -> &'static str {
74 match self {
75 BufferCfg::SpmcRing { .. } => "spmc_ring",
76 BufferCfg::SingleLatest => "single_latest",
77 BufferCfg::Mailbox => "mailbox",
78 }
79 }
80
81 pub fn estimated_memory_bytes(&self, item_size: usize, consumer_count: usize) -> usize {
85 match self {
86 BufferCfg::SpmcRing { capacity } => {
87 let buffer_size = capacity * item_size;
89 let consumer_overhead = consumer_count * 64; buffer_size + consumer_overhead
91 }
92 BufferCfg::SingleLatest => {
93 let buffer_size = item_size + 8; let consumer_overhead = consumer_count * 16; buffer_size + consumer_overhead
97 }
98 BufferCfg::Mailbox => {
99 let buffer_size = item_size + 8; let notify_overhead = 32; let consumer_overhead = consumer_count * 16; buffer_size + notify_overhead + consumer_overhead
104 }
105 }
106 }
107}
108
109impl Default for BufferCfg {
110 fn default() -> Self {
112 BufferCfg::SpmcRing { capacity: 1024 }
113 }
114}
115
116impl fmt::Display for BufferCfg {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 BufferCfg::SpmcRing { capacity } => write!(f, "SpmcRing(capacity={})", capacity),
120 BufferCfg::SingleLatest => write!(f, "SingleLatest"),
121 BufferCfg::Mailbox => write!(f, "Mailbox"),
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_buffer_cfg_validation() {
132 assert!(BufferCfg::SpmcRing { capacity: 1 }.validate().is_ok());
134 assert!(BufferCfg::SpmcRing { capacity: 1024 }.validate().is_ok());
135 assert!(BufferCfg::SingleLatest.validate().is_ok());
136 assert!(BufferCfg::Mailbox.validate().is_ok());
137
138 assert!(BufferCfg::SpmcRing { capacity: 0 }.validate().is_err());
140 }
141
142 #[test]
143 fn test_buffer_cfg_default() {
144 let cfg = BufferCfg::default();
145 assert_eq!(cfg, BufferCfg::SpmcRing { capacity: 1024 });
146 assert!(cfg.validate().is_ok());
147 }
148
149 #[test]
150 fn test_buffer_cfg_names() {
151 assert_eq!(BufferCfg::SpmcRing { capacity: 100 }.name(), "spmc_ring");
152 assert_eq!(BufferCfg::SingleLatest.name(), "single_latest");
153 assert_eq!(BufferCfg::Mailbox.name(), "mailbox");
154 }
155
156 #[test]
157 #[cfg(feature = "std")]
158 fn test_buffer_cfg_display() {
159 assert_eq!(
160 format!("{}", BufferCfg::SpmcRing { capacity: 512 }),
161 "SpmcRing(capacity=512)"
162 );
163 assert_eq!(format!("{}", BufferCfg::SingleLatest), "SingleLatest");
164 assert_eq!(format!("{}", BufferCfg::Mailbox), "Mailbox");
165 }
166
167 #[test]
168 fn test_estimated_memory() {
169 let cfg = BufferCfg::SpmcRing { capacity: 1024 };
171 let mem = cfg.estimated_memory_bytes(100, 3);
172 assert!(mem > 102_000 && mem < 103_000);
174
175 let cfg = BufferCfg::SingleLatest;
177 let mem = cfg.estimated_memory_bytes(100, 3);
178 assert!(mem > 100 && mem < 200);
180
181 let cfg = BufferCfg::Mailbox;
183 let mem = cfg.estimated_memory_bytes(100, 3);
184 assert!(mem > 140 && mem < 250);
186 }
187
188 #[test]
189 fn test_clone_and_equality() {
190 let cfg1 = BufferCfg::SpmcRing { capacity: 512 };
191 let cfg2 = cfg1.clone();
192 assert_eq!(cfg1, cfg2);
193
194 let cfg3 = BufferCfg::SingleLatest;
195 assert_ne!(cfg1, cfg3);
196 }
197}