etcd_txn_parser/
operation.rs1use elyze::acceptor::Acceptor;
4use elyze::bytes::components::groups::GroupKind;
5use elyze::bytes::primitives::string::DataString;
6use elyze::bytes::primitives::whitespace::OptionalWhitespaces;
7use elyze::bytes::token::Token;
8use elyze::errors::{ParseError, ParseResult};
9use elyze::peek::{peek, UntilEnd};
10use elyze::peeker::Peeker;
11use elyze::scanner::Scanner;
12use elyze::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 peeked = {
37 let peeked = Peeker::new(scanner)
38 .add_peekable(Token::Whitespace)
39 .add_peekable(UntilEnd::default())
40 .peek()?
41 .ok_or(ParseError::UnexpectedToken)?;
42 peeked
43 };
44
45 scanner.bump_by(peeked.end_slice);
46 Ok(UnquotedString(peeked.peeked_slice()))
47 }
48}
49
50pub struct Data<'a> {
55 pub(crate) data: &'a [u8],
56}
57
58impl<'a> Visitor<'a, u8> for Data<'a> {
59 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
60 let accepted = Acceptor::new(scanner)
61 .try_or(|x: QuotedString| x.0)?
62 .try_or(|x: UnquotedString| x.0)?
63 .finish()
64 .ok_or(ParseError::UnexpectedToken)?;
65 Ok(Data { data: accepted })
66 }
67}
68
69#[derive(Debug, PartialEq)]
75pub struct PutData<'a> {
76 pub key: &'a [u8],
78 pub value: &'a [u8],
80}
81
82impl<'a> Visitor<'a, u8> for PutData<'a> {
83 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
84 OptionalWhitespaces::accept(scanner)?;
85 let command = DataString::<&str>::accept(scanner)?.0;
86 if command != "put" {
87 return Err(ParseError::UnexpectedToken);
88 }
89 OptionalWhitespaces::accept(scanner)?;
90 let key = Data::accept(scanner)?.data;
91 OptionalWhitespaces::accept(scanner)?;
92 let value = Data::accept(scanner)?.data;
93 OptionalWhitespaces::accept(scanner)?;
94 Ok(PutData { key, value })
95 }
96}
97
98#[derive(Debug, PartialEq)]
104pub struct DeleteData<'a> {
105 pub key: &'a [u8],
107}
108
109impl<'a> Visitor<'a, u8> for DeleteData<'a> {
110 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
111 OptionalWhitespaces::accept(scanner)?;
112 let command = DataString::<&str>::accept(scanner)?.0;
113 if command != "del" {
114 return Err(ParseError::UnexpectedToken);
115 }
116 OptionalWhitespaces::accept(scanner)?;
117 let until_ln = Peeker::new(scanner)
118 .add_peekable(Token::Ln)
119 .add_peekable(UntilEnd::default())
120 .peek()?
121 .ok_or(ParseError::UnexpectedToken)?;
122 let mut scanner_until_ln = Scanner::new(until_ln.peeked_slice());
123
124 let key = Data::accept(&mut scanner_until_ln)?.data;
125 scanner.bump_by(scanner_until_ln.current_position());
126 OptionalWhitespaces::accept(scanner)?;
127
128 Ok(DeleteData { key })
129 }
130}
131
132#[derive(Debug, PartialEq)]
138pub struct GetData<'a> {
139 pub key: &'a [u8],
141}
142
143impl<'a> Visitor<'a, u8> for GetData<'a> {
144 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
145 OptionalWhitespaces::accept(scanner)?;
146 let command = DataString::<&str>::accept(scanner)?.0;
147 if command != "get" {
148 return Err(ParseError::UnexpectedToken);
149 }
150
151 OptionalWhitespaces::accept(scanner)?;
152
153 let until_ln = Peeker::new(scanner)
154 .add_peekable(Token::Ln)
155 .add_peekable(UntilEnd::default())
156 .peek()?
157 .ok_or(ParseError::UnexpectedToken)?;
158 let mut scanner_until_ln = Scanner::new(until_ln.peeked_slice());
159
160 let key = Data::accept(&mut scanner_until_ln)?.data;
161 scanner.bump_by(scanner_until_ln.current_position());
162 OptionalWhitespaces::accept(scanner)?;
163
164 Ok(GetData { key })
165 }
166}
167
168#[derive(Debug, PartialEq)]
174pub enum Operation<'a> {
175 Put(PutData<'a>),
177 Delete(DeleteData<'a>),
179 Get(GetData<'a>),
181}
182
183impl<'a> Visitor<'a, u8> for Operation<'a> {
184 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
185 let operation = Acceptor::new(scanner)
186 .try_or(Operation::Put)?
187 .try_or(Operation::Delete)?
188 .try_or(Operation::Get)?
189 .finish()
190 .ok_or(ParseError::UnexpectedToken)?;
191 Ok(operation)
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use crate::operation::GetData;
198 use elyze::visitor::Visitor;
199
200 #[test]
201 fn test_get_data() {
202 let data = b"get \"key\"";
203 let mut scanner = elyze::scanner::Scanner::new(data);
204 let result = super::GetData::accept(&mut scanner);
205 assert!(matches!(result, Ok(GetData { key: b"key" })));
206
207 let data = b"get key";
208 let mut scanner = elyze::scanner::Scanner::new(data);
209 let result = super::GetData::accept(&mut scanner);
210 assert!(matches!(result, Ok(GetData { key: b"key" })));
211 }
212
213 #[test]
214 fn test_delete_data() {
215 let data = b"del \"key\"";
216 let mut scanner = elyze::scanner::Scanner::new(data);
217 let result = super::DeleteData::accept(&mut scanner);
218 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
219
220 let data = b"del key";
221 let mut scanner = elyze::scanner::Scanner::new(data);
222 let result = super::DeleteData::accept(&mut scanner);
223 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
224 }
225
226 #[test]
227 fn test_put_data() {
228 let data = b"put \"key\" \"value\"";
229 let mut scanner = elyze::scanner::Scanner::new(data);
230 let result = super::PutData::accept(&mut scanner);
231 assert!(matches!(
232 result,
233 Ok(super::PutData {
234 key: b"key",
235 value: b"value"
236 })
237 ));
238
239 let data = b"put key value";
240 let mut scanner = elyze::scanner::Scanner::new(data);
241 let result = super::PutData::accept(&mut scanner);
242
243 if let Ok(result) = &result {
244 println!("{:?}", String::from_utf8_lossy(result.key));
245 println!("{:?}", String::from_utf8_lossy(result.value));
246 }
247
248 assert!(matches!(
249 result,
250 Ok(super::PutData {
251 key: b"key",
252 value: b"value"
253 })
254 ));
255 }
256}