ddex_parser/parser/
mode.rs

1// core/src/parser/mode.rs
2//! Parser mode selection (DOM vs Stream)
3
4use std::io::{BufRead, Seek, SeekFrom};
5
6/// Parser mode
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ParseMode {
9    /// Use DOM parsing for smaller files
10    Dom,
11    /// Use streaming for larger files
12    Stream,
13    /// Automatically choose based on file size
14    Auto,
15}
16
17impl Default for ParseMode {
18    fn default() -> Self {
19        Self::Auto
20    }
21}
22
23/// Mode selector for choosing parsing strategy
24pub struct ModeSelector {
25    threshold: u64,
26}
27
28impl Default for ModeSelector {
29    fn default() -> Self {
30        Self {
31            threshold: 10 * 1024 * 1024, // 10MB default threshold
32        }
33    }
34}
35
36impl ModeSelector {
37    pub fn new(threshold: u64) -> Self {
38        Self { threshold }
39    }
40    
41    /// Select parsing mode based on file size
42    pub fn select_mode<R: BufRead + Seek>(&self, reader: &mut R, mode: ParseMode) -> Result<ParseMode, std::io::Error> {
43        match mode {
44            ParseMode::Dom | ParseMode::Stream => Ok(mode),
45            ParseMode::Auto => {
46                // Try to determine file size
47                let current_pos = reader.stream_position()?;
48                let size = reader.seek(SeekFrom::End(0))?;
49                reader.seek(SeekFrom::Start(current_pos))?;
50                
51                if size > self.threshold {
52                    Ok(ParseMode::Stream)
53                } else {
54                    Ok(ParseMode::Dom)
55                }
56            }
57        }
58    }
59    
60    /// Select mode without seeking (for non-seekable streams)
61    pub fn select_mode_hint(&self, size_hint: Option<u64>, mode: ParseMode) -> ParseMode {
62        match mode {
63            ParseMode::Dom | ParseMode::Stream => mode,
64            ParseMode::Auto => {
65                if let Some(size) = size_hint {
66                    if size > self.threshold {
67                        ParseMode::Stream
68                    } else {
69                        ParseMode::Dom
70                    }
71                } else {
72                    // Default to streaming for unknown size
73                    ParseMode::Stream
74                }
75            }
76        }
77    }
78}