etcd_txn_parser/
operation.rs1use noa_parser::acceptor::Acceptor;
4use noa_parser::bytes::components::groups::GroupKind;
5use noa_parser::bytes::primitives::string::DataString;
6use noa_parser::bytes::primitives::whitespace::OptionalWhitespaces;
7use noa_parser::bytes::token::Token;
8use noa_parser::errors::{ParseError, ParseResult};
9use noa_parser::peek::{peek, Until, UntilEnd};
10use noa_parser::peeker::Peeker;
11use noa_parser::scanner::Scanner;
12use noa_parser::visitor::Visitor;
13
14struct QuotedString<'a>(&'a [u8]);
19
20impl<'a> Visitor<'a, u8> for QuotedString<'a> {
21 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
22 let peeked = peek(GroupKind::DoubleQuotes, scanner)?.ok_or(ParseError::UnexpectedToken)?;
23 scanner.bump_by(peeked.end_slice);
24 Ok(QuotedString(peeked.peeked_slice()))
25 }
26}
27
28struct UnquotedString<'a>(&'a [u8]);
33
34impl<'a> Visitor<'a, u8> for UnquotedString<'a> {
35 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
36 let mut inner_scanner = Scanner::new(&scanner.data()[scanner.current_position()..]);
37
38 let peeked = Peeker::new(&mut inner_scanner)
39 .add_peekable(Until::new(Token::Whitespace))
40 .add_peekable(UntilEnd::default())
41 .peek()?
42 .ok_or(ParseError::UnexpectedToken)?;
43
44 let current_position = scanner.current_position();
46 let data =
47 UnquotedString(&scanner.data()[current_position..current_position + peeked.end_slice]);
48
49 scanner.bump_by(peeked.end_slice);
50 Ok(data)
51 }
52}
53
54pub struct Data<'a> {
59 pub(crate) data: &'a [u8],
60}
61
62impl<'a> Visitor<'a, u8> for Data<'a> {
63 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
64 let accepted = Acceptor::new(scanner)
65 .try_or(|x: QuotedString| x.0)?
66 .try_or(|x: UnquotedString| x.0)?
67 .finish()
68 .ok_or(ParseError::UnexpectedToken)?;
69 Ok(Data { data: accepted })
70 }
71}
72
73#[derive(Debug, PartialEq)]
79pub struct PutData<'a> {
80 pub key: &'a [u8],
82 pub value: &'a [u8],
84}
85
86impl<'a> Visitor<'a, u8> for PutData<'a> {
87 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
88 OptionalWhitespaces::accept(scanner)?;
89 let command = DataString::<&str>::accept(scanner)?.0;
90 if command != "put" {
91 return Err(ParseError::UnexpectedToken);
92 }
93 OptionalWhitespaces::accept(scanner)?;
94 let key = Data::accept(scanner)?.data;
95 OptionalWhitespaces::accept(scanner)?;
96 let value = Data::accept(scanner)?.data;
97 OptionalWhitespaces::accept(scanner)?;
98 Ok(PutData { key, value })
99 }
100}
101
102#[derive(Debug, PartialEq)]
108pub struct DeleteData<'a> {
109 key: &'a [u8],
111}
112
113impl<'a> Visitor<'a, u8> for DeleteData<'a> {
114 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
115 OptionalWhitespaces::accept(scanner)?;
116 let command = DataString::<&str>::accept(scanner)?.0;
117 if command != "del" {
118 return Err(ParseError::UnexpectedToken);
119 }
120 OptionalWhitespaces::accept(scanner)?;
121 let key = Data::accept(scanner)?.data;
122 OptionalWhitespaces::accept(scanner)?;
123 Ok(DeleteData { key })
124 }
125}
126
127#[derive(Debug, PartialEq)]
133pub struct GetData<'a> {
134 key: &'a [u8],
136}
137
138impl<'a> Visitor<'a, u8> for GetData<'a> {
139 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
140 OptionalWhitespaces::accept(scanner)?;
141 let command = DataString::<&str>::accept(scanner)?.0;
142 if command != "get" {
143 return Err(ParseError::UnexpectedToken);
144 }
145 OptionalWhitespaces::accept(scanner)?;
146 let key = Data::accept(scanner)?.data;
147 OptionalWhitespaces::accept(scanner)?;
148 Ok(GetData { key })
149 }
150}
151
152#[derive(Debug, PartialEq)]
158pub enum Operation<'a> {
159 Put(PutData<'a>),
161 Delete(DeleteData<'a>),
163 Get(GetData<'a>),
165}
166
167impl<'a> Visitor<'a, u8> for Operation<'a> {
168 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
169 let operation = Acceptor::new(scanner)
170 .try_or(Operation::Put)?
171 .try_or(Operation::Delete)?
172 .try_or(Operation::Get)?
173 .finish()
174 .ok_or(ParseError::UnexpectedToken)?;
175 Ok(operation)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use crate::operation::GetData;
182 use noa_parser::visitor::Visitor;
183
184 #[test]
185 fn test_get_data() {
186 let data = b"get \"key\"";
187 let mut scanner = noa_parser::scanner::Scanner::new(data);
188 let result = super::GetData::accept(&mut scanner);
189 assert!(matches!(result, Ok(GetData { key: b"key" })));
190
191 let data = b"get key";
192 let mut scanner = noa_parser::scanner::Scanner::new(data);
193 let result = super::GetData::accept(&mut scanner);
194 assert!(matches!(result, Ok(GetData { key: b"key" })));
195 }
196
197 #[test]
198 fn test_delete_data() {
199 let data = b"del \"key\"";
200 let mut scanner = noa_parser::scanner::Scanner::new(data);
201 let result = super::DeleteData::accept(&mut scanner);
202 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
203
204 let data = b"del key";
205 let mut scanner = noa_parser::scanner::Scanner::new(data);
206 let result = super::DeleteData::accept(&mut scanner);
207 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
208 }
209
210 #[test]
211 fn test_put_data() {
212 let data = b"put \"key\" \"value\"";
213 let mut scanner = noa_parser::scanner::Scanner::new(data);
214 let result = super::PutData::accept(&mut scanner);
215 assert!(matches!(
216 result,
217 Ok(super::PutData {
218 key: b"key",
219 value: b"value"
220 })
221 ));
222
223 let data = b"put key value";
224 let mut scanner = noa_parser::scanner::Scanner::new(data);
225 let result = super::PutData::accept(&mut scanner);
226 assert!(matches!(
227 result,
228 Ok(super::PutData {
229 key: b"key",
230 value: b"value"
231 })
232 ));
233 }
234}