Skip to main content

memscope_rs/capture/backends/
export_options.rs

1//! Export options for memory tracking
2
3/// Export options for JSON export - user-controllable settings
4#[derive(Debug, Clone)]
5pub struct ExportOptions {
6    /// Include system allocations in full enrichment (default: false)
7    pub include_system_allocations: bool,
8    /// Enable verbose logging during export (default: false)
9    pub verbose_logging: bool,
10    /// Buffer size for file I/O in bytes (default: 64KB)
11    pub buffer_size: usize,
12}
13
14impl Default for ExportOptions {
15    fn default() -> Self {
16        Self {
17            include_system_allocations: false,
18            verbose_logging: false,
19            buffer_size: 64 * 1024,
20        }
21    }
22}
23
24impl ExportOptions {
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    pub fn include_system_allocations(mut self, include: bool) -> Self {
30        self.include_system_allocations = include;
31        self
32    }
33
34    pub fn verbose_logging(mut self, verbose: bool) -> Self {
35        self.verbose_logging = verbose;
36        self
37    }
38
39    pub fn buffer_size(mut self, size: usize) -> Self {
40        self.buffer_size = size;
41        self
42    }
43}
44
45/// Internal export mode derived from options
46#[derive(Debug, Clone, Copy)]
47pub enum ExportMode {
48    UserFocused,
49    Complete,
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    /// Objective: Verify ExportOptions creation with default values
57    /// Invariants: Default should have include_system_allocations=false, verbose_logging=false, buffer_size=64KB
58    #[test]
59    fn test_export_options_default() {
60        let options = ExportOptions::default();
61
62        assert!(
63            !options.include_system_allocations,
64            "Default include_system_allocations should be false"
65        );
66        assert!(
67            !options.verbose_logging,
68            "Default verbose_logging should be false"
69        );
70        assert_eq!(
71            options.buffer_size,
72            64 * 1024,
73            "Default buffer_size should be 64KB"
74        );
75    }
76
77    /// Objective: Verify ExportOptions::new() creates default options
78    /// Invariants: new() should return same as default()
79    #[test]
80    fn test_export_options_new() {
81        let options = ExportOptions::new();
82        let default_options = ExportOptions::default();
83
84        assert_eq!(
85            options.include_system_allocations, default_options.include_system_allocations,
86            "new() should match default()"
87        );
88        assert_eq!(
89            options.verbose_logging, default_options.verbose_logging,
90            "new() should match default()"
91        );
92        assert_eq!(
93            options.buffer_size, default_options.buffer_size,
94            "new() should match default()"
95        );
96    }
97
98    /// Objective: Verify include_system_allocations builder method
99    /// Invariants: Should set include_system_allocations to true
100    #[test]
101    fn test_export_options_include_system_allocations() {
102        let options = ExportOptions::new().include_system_allocations(true);
103
104        assert!(
105            options.include_system_allocations,
106            "include_system_allocations should be true"
107        );
108    }
109
110    /// Objective: Verify include_system_allocations can be set to false
111    /// Invariants: Should set include_system_allocations to false
112    #[test]
113    fn test_export_options_exclude_system_allocations() {
114        let options = ExportOptions::new().include_system_allocations(false);
115
116        assert!(
117            !options.include_system_allocations,
118            "include_system_allocations should be false"
119        );
120    }
121
122    /// Objective: Verify verbose_logging builder method
123    /// Invariants: Should set verbose_logging to true
124    #[test]
125    fn test_export_options_verbose_logging() {
126        let options = ExportOptions::new().verbose_logging(true);
127
128        assert!(options.verbose_logging, "verbose_logging should be true");
129    }
130
131    /// Objective: Verify buffer_size builder method
132    /// Invariants: Should set custom buffer size
133    #[test]
134    fn test_export_options_buffer_size() {
135        let options = ExportOptions::new().buffer_size(128 * 1024);
136
137        assert_eq!(
138            options.buffer_size,
139            128 * 1024,
140            "buffer_size should be 128KB"
141        );
142    }
143
144    /// Objective: Verify chained builder methods
145    /// Invariants: All builder methods should work together
146    #[test]
147    fn test_export_options_chained_builders() {
148        let options = ExportOptions::new()
149            .include_system_allocations(true)
150            .verbose_logging(true)
151            .buffer_size(256 * 1024);
152
153        assert!(
154            options.include_system_allocations,
155            "include_system_allocations should be true"
156        );
157        assert!(options.verbose_logging, "verbose_logging should be true");
158        assert_eq!(
159            options.buffer_size,
160            256 * 1024,
161            "buffer_size should be 256KB"
162        );
163    }
164
165    /// Objective: Verify Clone trait implementation
166    /// Invariants: Cloned options should have same values
167    #[test]
168    fn test_export_options_clone() {
169        let original = ExportOptions::new()
170            .include_system_allocations(true)
171            .verbose_logging(true)
172            .buffer_size(128 * 1024);
173
174        let cloned = original.clone();
175
176        assert_eq!(
177            original.include_system_allocations, cloned.include_system_allocations,
178            "Cloned include_system_allocations should match"
179        );
180        assert_eq!(
181            original.verbose_logging, cloned.verbose_logging,
182            "Cloned verbose_logging should match"
183        );
184        assert_eq!(
185            original.buffer_size, cloned.buffer_size,
186            "Cloned buffer_size should match"
187        );
188    }
189
190    /// Objective: Verify Debug trait implementation
191    /// Invariants: Debug output should contain field names
192    #[test]
193    fn test_export_options_debug() {
194        let options = ExportOptions::new();
195        let debug_str = format!("{:?}", options);
196
197        assert!(
198            debug_str.contains("ExportOptions"),
199            "Debug should contain struct name"
200        );
201        assert!(
202            debug_str.contains("include_system_allocations"),
203            "Debug should contain field name"
204        );
205        assert!(
206            debug_str.contains("verbose_logging"),
207            "Debug should contain field name"
208        );
209        assert!(
210            debug_str.contains("buffer_size"),
211            "Debug should contain field name"
212        );
213    }
214
215    /// Objective: Verify ExportMode variants
216    /// Invariants: All variants should have debug representation
217    #[test]
218    fn test_export_mode_variants() {
219        let user_focused = ExportMode::UserFocused;
220        let complete = ExportMode::Complete;
221
222        let debug_focused = format!("{:?}", user_focused);
223        let debug_complete = format!("{:?}", complete);
224
225        assert!(
226            debug_focused.contains("UserFocused"),
227            "Debug should contain UserFocused"
228        );
229        assert!(
230            debug_complete.contains("Complete"),
231            "Debug should contain Complete"
232        );
233    }
234
235    /// Objective: Verify ExportMode Clone trait
236    /// Invariants: Cloned mode should be equal
237    #[test]
238    fn test_export_mode_clone() {
239        let original = ExportMode::Complete;
240        let cloned = original;
241
242        assert!(
243            matches!(cloned, ExportMode::Complete),
244            "Cloned mode should be Complete"
245        );
246    }
247
248    /// Objective: Verify ExportMode Copy trait
249    /// Invariants: Copy should work implicitly
250    #[test]
251    fn test_export_mode_copy() {
252        let original = ExportMode::UserFocused;
253        let copied = original;
254
255        assert!(
256            matches!(original, ExportMode::UserFocused),
257            "Original should still be valid after copy"
258        );
259        assert!(
260            matches!(copied, ExportMode::UserFocused),
261            "Copied should be UserFocused"
262        );
263    }
264
265    /// Objective: Verify zero buffer_size
266    /// Invariants: Should accept zero buffer size
267    #[test]
268    fn test_export_options_zero_buffer_size() {
269        let options = ExportOptions::new().buffer_size(0);
270
271        assert_eq!(options.buffer_size, 0, "buffer_size should be 0");
272    }
273
274    /// Objective: Verify large buffer_size
275    /// Invariants: Should accept large buffer size
276    #[test]
277    fn test_export_options_large_buffer_size() {
278        let large_size = 1024 * 1024 * 1024;
279        let options = ExportOptions::new().buffer_size(large_size);
280
281        assert_eq!(options.buffer_size, large_size, "buffer_size should be 1GB");
282    }
283
284    /// Objective: Verify builder overwrites previous value
285    /// Invariants: Later builder call should override earlier
286    #[test]
287    fn test_export_options_builder_override() {
288        let options = ExportOptions::new().buffer_size(1024).buffer_size(2048);
289
290        assert_eq!(
291            options.buffer_size, 2048,
292            "Later buffer_size should override earlier"
293        );
294    }
295}