crdtosphere/memory/
macros.rs

1//! Memory configuration macros
2//!
3//! This module provides the `define_memory_config!` macro for easy creation
4//! of custom memory configurations.
5
6/// Macro to define a custom memory configuration
7///
8/// This macro creates a new struct that implements the `MemoryConfig` trait
9/// with user-specified values and automatic validation.
10///
11/// # Example
12///
13/// ```rust
14/// use crdtosphere::memory::define_memory_config;
15///
16/// define_memory_config! {
17///     name: MyPlatformConfig,
18///     total_memory: 64 * 1024,  // 64KB budget
19///     max_registers: 100,
20///     max_counters: 50,
21///     max_sets: 20,
22///     max_maps: 10,
23///     max_nodes: 32,
24/// }
25/// ```
26#[macro_export]
27macro_rules! define_memory_config {
28    (
29        name: $name:ident,
30        total_memory: $total:expr,
31        max_registers: $registers:expr,
32        max_counters: $counters:expr,
33        max_sets: $sets:expr,
34        max_maps: $maps:expr,
35        max_nodes: $nodes:expr
36        $(, max_set_elements: $set_elements:expr)?
37        $(, max_map_entries: $map_entries:expr)?
38        $(, max_history_size: $history:expr)?
39        $(, clock_memory_budget: $clock_budget:expr)?
40        $(, error_buffer_size: $error_buffer:expr)?
41        $(, memory_alignment: $alignment:expr)?
42        $(, cache_line_size: $cache_line:expr)?
43        $(,)?
44    ) => {
45        /// Custom memory configuration
46        #[derive(Debug, Clone, Copy)]
47        pub struct $name;
48
49        impl $crate::memory::MemoryConfig for $name {
50            const TOTAL_CRDT_MEMORY: usize = $total;
51            const MAX_REGISTERS: usize = $registers;
52            const MAX_COUNTERS: usize = $counters;
53            const MAX_SETS: usize = $sets;
54            const MAX_MAPS: usize = $maps;
55            const MAX_NODES: usize = $nodes;
56
57            // Optional parameters with defaults
58            const MAX_SET_ELEMENTS: usize = define_memory_config!(@default $($set_elements)?, 32);
59            const MAX_MAP_ENTRIES: usize = define_memory_config!(@default $($map_entries)?, 32);
60            const MAX_HISTORY_SIZE: usize = define_memory_config!(@default $($history)?, 4);
61            const CLOCK_MEMORY_BUDGET: usize = define_memory_config!(@default $($clock_budget)?, 512);
62            const ERROR_BUFFER_SIZE: usize = define_memory_config!(@default $($error_buffer)?, 256);
63            const MEMORY_ALIGNMENT: usize = define_memory_config!(@default $($alignment)?, 4);
64            const CACHE_LINE_SIZE: usize = define_memory_config!(@default $($cache_line)?, 32);
65        }
66
67        // Runtime validation available via validate() method
68        // Note: Call $name::validate() at runtime to check configuration
69    };
70
71    // Helper macro for default values
72    (@default $value:expr, $default:expr) => { $value };
73    (@default , $default:expr) => { $default };
74}
75
76// Re-export the macro for convenience
77pub use define_memory_config;
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82    use crate::memory::MemoryConfig;
83
84    define_memory_config! {
85        name: TestConfig,
86        total_memory: 16 * 1024,  // 16KB
87        max_registers: 25,
88        max_counters: 15,
89        max_sets: 10,
90        max_maps: 5,
91        max_nodes: 8,
92    }
93
94    #[test]
95    fn test_macro_generated_config() {
96        assert_eq!(TestConfig::TOTAL_CRDT_MEMORY, 16 * 1024);
97        assert_eq!(TestConfig::MAX_REGISTERS, 25);
98        assert_eq!(TestConfig::MAX_COUNTERS, 15);
99        assert_eq!(TestConfig::MAX_SETS, 10);
100        assert_eq!(TestConfig::MAX_MAPS, 5);
101        assert_eq!(TestConfig::MAX_NODES, 8);
102
103        // Check defaults
104        assert_eq!(TestConfig::MAX_SET_ELEMENTS, 32);
105        assert_eq!(TestConfig::MAX_MAP_ENTRIES, 32);
106        assert_eq!(TestConfig::MAX_HISTORY_SIZE, 4);
107        assert_eq!(TestConfig::MEMORY_ALIGNMENT, 4);
108    }
109
110    #[test]
111    fn test_macro_validation() {
112        // This should compile without panicking due to compile-time validation
113        assert!(TestConfig::validate().is_ok());
114    }
115
116    define_memory_config! {
117        name: CustomConfig,
118        total_memory: 8 * 1024,
119        max_registers: 10,
120        max_counters: 5,
121        max_sets: 3,
122        max_maps: 2,
123        max_nodes: 4,
124        max_set_elements: 16,
125        max_map_entries: 16,
126        memory_alignment: 8,
127    }
128
129    #[test]
130    fn test_macro_with_custom_values() {
131        assert_eq!(CustomConfig::MAX_SET_ELEMENTS, 16);
132        assert_eq!(CustomConfig::MAX_MAP_ENTRIES, 16);
133        assert_eq!(CustomConfig::MEMORY_ALIGNMENT, 8);
134        assert!(CustomConfig::validate().is_ok());
135    }
136}