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>(
43        &self,
44        reader: &mut R,
45        mode: ParseMode,
46    ) -> Result<ParseMode, std::io::Error> {
47        match mode {
48            ParseMode::Dom | ParseMode::Stream => Ok(mode),
49            ParseMode::Auto => {
50                // Try to determine file size
51                let current_pos = reader.stream_position()?;
52                let size = reader.seek(SeekFrom::End(0))?;
53                reader.seek(SeekFrom::Start(current_pos))?;
54
55                if size > self.threshold {
56                    Ok(ParseMode::Stream)
57                } else {
58                    Ok(ParseMode::Dom)
59                }
60            }
61        }
62    }
63
64    /// Select mode without seeking (for non-seekable streams)
65    pub fn select_mode_hint(&self, size_hint: Option<u64>, mode: ParseMode) -> ParseMode {
66        match mode {
67            ParseMode::Dom | ParseMode::Stream => mode,
68            ParseMode::Auto => {
69                if let Some(size) = size_hint {
70                    if size > self.threshold {
71                        ParseMode::Stream
72                    } else {
73                        ParseMode::Dom
74                    }
75                } else {
76                    // Default to streaming for unknown size
77                    ParseMode::Stream
78                }
79            }
80        }
81    }
82}