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 key = Data::accept(scanner)?.data;
118 OptionalWhitespaces::accept(scanner)?;
119 Ok(DeleteData { key })
120 }
121}
122
123#[derive(Debug, PartialEq)]
129pub struct GetData<'a> {
130 pub key: &'a [u8],
132}
133
134impl<'a> Visitor<'a, u8> for GetData<'a> {
135 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
136 OptionalWhitespaces::accept(scanner)?;
137 let command = DataString::<&str>::accept(scanner)?.0;
138 if command != "get" {
139 return Err(ParseError::UnexpectedToken);
140 }
141 OptionalWhitespaces::accept(scanner)?;
142 let key = Data::accept(scanner)?.data;
143 OptionalWhitespaces::accept(scanner)?;
144 Ok(GetData { key })
145 }
146}
147
148#[derive(Debug, PartialEq)]
154pub enum Operation<'a> {
155 Put(PutData<'a>),
157 Delete(DeleteData<'a>),
159 Get(GetData<'a>),
161}
162
163impl<'a> Visitor<'a, u8> for Operation<'a> {
164 fn accept(scanner: &mut Scanner<'a, u8>) -> ParseResult<Self> {
165 let operation = Acceptor::new(scanner)
166 .try_or(Operation::Put)?
167 .try_or(Operation::Delete)?
168 .try_or(Operation::Get)?
169 .finish()
170 .ok_or(ParseError::UnexpectedToken)?;
171 Ok(operation)
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use crate::operation::GetData;
178 use elyze::visitor::Visitor;
179
180 #[test]
181 fn test_get_data() {
182 let data = b"get \"key\"";
183 let mut scanner = elyze::scanner::Scanner::new(data);
184 let result = super::GetData::accept(&mut scanner);
185 assert!(matches!(result, Ok(GetData { key: b"key" })));
186
187 let data = b"get key";
188 let mut scanner = elyze::scanner::Scanner::new(data);
189 let result = super::GetData::accept(&mut scanner);
190 assert!(matches!(result, Ok(GetData { key: b"key" })));
191 }
192
193 #[test]
194 fn test_delete_data() {
195 let data = b"del \"key\"";
196 let mut scanner = elyze::scanner::Scanner::new(data);
197 let result = super::DeleteData::accept(&mut scanner);
198 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
199
200 let data = b"del key";
201 let mut scanner = elyze::scanner::Scanner::new(data);
202 let result = super::DeleteData::accept(&mut scanner);
203 assert!(matches!(result, Ok(super::DeleteData { key: b"key" })));
204 }
205
206 #[test]
207 fn test_put_data() {
208 let data = b"put \"key\" \"value\"";
209 let mut scanner = elyze::scanner::Scanner::new(data);
210 let result = super::PutData::accept(&mut scanner);
211 assert!(matches!(
212 result,
213 Ok(super::PutData {
214 key: b"key",
215 value: b"value"
216 })
217 ));
218
219 let data = b"put key value";
220 let mut scanner = elyze::scanner::Scanner::new(data);
221 let result = super::PutData::accept(&mut scanner);
222
223 if let Ok(result) = &result {
224 println!("{:?}", String::from_utf8_lossy(result.key));
225 println!("{:?}", String::from_utf8_lossy(result.value));
226 }
227
228 assert!(matches!(
229 result,
230 Ok(super::PutData {
231 key: b"key",
232 value: b"value"
233 })
234 ));
235 }
236}