flexpiler/common/rustc/block/
identifier_with_data_start_finish.rs

1use super::constants::*;
2
3use crate::block;
4use crate::parser::error;
5use crate::reader;
6
7
8enum Context {
9    Initial,
10
11    Comment,
12    String,
13    FinishedFreestanding,
14    FinishedWithDataStart,
15    Error,
16}
17
18
19#[derive(Clone)]
20pub enum Result {
21    Freestanding(String),
22    DataStartFinish(String),
23}
24
25
26pub struct IdentifierWithDataStartFinish {
27    error_source: error::Source,
28    context: Context,
29    string: std::string::String,
30}
31
32
33impl IdentifierWithDataStartFinish {
34    pub fn new() -> IdentifierWithDataStartFinish {
35        IdentifierWithDataStartFinish {
36            error_source: error::Source::NoContent,
37            context: Context::Initial,
38            string: std::string::String::new(),
39        }
40    }
41}
42
43
44impl Default for IdentifierWithDataStartFinish {
45    fn default() -> Self {
46        return Self::new();
47    }
48}
49
50
51impl block::Trait for IdentifierWithDataStartFinish {
52    type Result = Result;
53
54    fn advance_result(&mut self, read_byte: u8) -> block::AdvanceResult {
55        match (&self.context, read_byte) {
56            // Accept comments in initial state
57            (&Context::Initial,
58                DENOMINATOR_COMMENT) => {
59                self.context = Context::Comment;
60                return block::AdvanceResult::Continuous;
61            },
62
63            // Ignore newline, space, tab at initial state
64            (&Context::Initial,
65                DENOMINATOR_NEW_LINE)
66            | (&Context::Initial,
67                DENOMINATOR_SPACE)
68            | (&Context::Initial,
69                DENOMINATOR_TAB) => {
70                return block::AdvanceResult::Continuous;
71            },
72
73            // On encountering the first non ignorable | comment char
74            // Change deserializer to string and add read_byte as first character
75            (&Context::Initial,
76                _) => {
77                self.string.push(read_byte as char);
78                self.context = Context::String;
79                return block::AdvanceResult::Continuous;
80            },
81
82            (&Context::String,
83                DENOMINATOR_SPACE)
84            | (&Context::String,
85                DENOMINATOR_NEW_LINE)
86            | (&Context::String,
87                DENOMINATOR_TAB) => {
88                self.context = Context::FinishedFreestanding;
89                return block::AdvanceResult::Finished;
90            },
91
92            (&Context::String,
93                DENOMINATOR_DATA_START) => {
94                self.context = Context::FinishedWithDataStart;
95                return block::AdvanceResult::Finished;
96            },
97
98            // On encountering regular
99            (&Context::String,
100                _) => {
101                self.string.push(read_byte as char);
102                return block::AdvanceResult::Continuous;
103            },
104
105            // On newline from comment reset deserializer
106            (&Context::Comment,
107                DENOMINATOR_NEW_LINE) => {
108                self.context = Context::Initial;
109                return block::AdvanceResult::Continuous;
110            },
111
112            // Ignore any other character in a comment
113            (&Context::Comment,
114                _) => {
115                return block::AdvanceResult::Continuous;
116            },
117
118            (&Context::FinishedWithDataStart,
119                _) => {
120                return block::AdvanceResult::Finished;
121            },
122
123            (&Context::FinishedFreestanding,
124                _) => {
125                return block::AdvanceResult::Finished;
126            },
127
128            (&Context::Error,
129                _) => {
130                return block::AdvanceResult::Error;
131            },
132        }
133    }
134
135    fn into_result(self) -> std::result::Result<Result, error::Source> {
136        match self.context {
137            Context::Initial
138            | Context::Comment
139            | Context::String
140            | Context::Error => {
141                return Err(self.error_source);
142            },
143            Context::FinishedFreestanding => {
144                return Ok(Result::Freestanding(self.string))
145            },
146            Context::FinishedWithDataStart => {
147                return Ok(Result::DataStartFinish(self.string))
148            },
149        }
150    }
151}