ddex_parser/parser/
mode.rs1use std::io::{BufRead, Seek, SeekFrom};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ParseMode {
9 Dom,
11 Stream,
13 Auto,
15}
16
17impl Default for ParseMode {
18 fn default() -> Self {
19 Self::Auto
20 }
21}
22
23pub struct ModeSelector {
25 threshold: u64,
26}
27
28impl Default for ModeSelector {
29 fn default() -> Self {
30 Self {
31 threshold: 10 * 1024 * 1024, }
33 }
34}
35
36impl ModeSelector {
37 pub fn new(threshold: u64) -> Self {
38 Self { threshold }
39 }
40
41 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 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 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 ParseMode::Stream
78 }
79 }
80 }
81 }
82}