cqlite_core/parser/
binary.rs1use crate::cql::ast::*;
8use crate::cql::config::ParserConfig;
9use crate::cql::traits::{CqlParser, ParserBackendInfo, ParserFeature, PerformanceCharacteristics};
10use crate::error::{Error, Result};
11use async_trait::async_trait;
12
13#[derive(Debug)]
15pub struct SSTableParser {}
16
17impl SSTableParser {
18 pub fn new(_config: ParserConfig) -> Result<Self> {
20 Ok(Self {})
21 }
22
23 pub fn backend_info() -> ParserBackendInfo {
25 ParserBackendInfo {
26 name: "binary".to_string(),
27 version: "1.0.0".to_string(),
28 features: vec![ParserFeature::Streaming],
29 performance: PerformanceCharacteristics {
30 statements_per_second: 50_000,
31 memory_per_statement: 512,
32 startup_time_ms: 1,
33 async_support: true,
34 },
35 }
36 }
37}
38
39#[async_trait]
40impl CqlParser for SSTableParser {
41 async fn parse(&self, _input: &str) -> Result<CqlStatement> {
42 Err(Error::invalid_operation(
43 "Binary parser does not support text parsing".to_string(),
44 ))
45 }
46
47 async fn parse_type(&self, _input: &str) -> Result<CqlDataType> {
48 Err(Error::invalid_operation(
49 "Binary parser does not support text parsing".to_string(),
50 ))
51 }
52
53 async fn parse_expression(&self, _input: &str) -> Result<CqlExpression> {
54 Err(Error::invalid_operation(
55 "Binary parser does not support text parsing".to_string(),
56 ))
57 }
58
59 async fn parse_identifier(&self, _input: &str) -> Result<CqlIdentifier> {
60 Err(Error::invalid_operation(
61 "Binary parser does not support text parsing".to_string(),
62 ))
63 }
64
65 async fn parse_literal(&self, _input: &str) -> Result<CqlLiteral> {
66 Err(Error::invalid_operation(
67 "Binary parser does not support text parsing".to_string(),
68 ))
69 }
70
71 async fn parse_column_definitions(&self, _input: &str) -> Result<Vec<CqlColumnDef>> {
72 Err(Error::invalid_operation(
73 "Binary parser does not support text parsing".to_string(),
74 ))
75 }
76
77 async fn parse_table_options(&self, _input: &str) -> Result<CqlTableOptions> {
78 Err(Error::invalid_operation(
79 "Binary parser does not support text parsing".to_string(),
80 ))
81 }
82
83 fn validate_syntax(&self, _input: &str) -> bool {
84 false }
86
87 fn backend_info(&self) -> ParserBackendInfo {
88 Self::backend_info()
89 }
90}
91
92#[derive(Debug, thiserror::Error)]
94pub enum CQLiteParseError {
95 #[error("Parse error: {0}")]
96 ParseError(String),
97
98 #[error("Invalid format: {0}")]
99 InvalidFormat(String),
100
101 #[error("Unsupported operation: {0}")]
102 Unsupported(String),
103}
104
105impl From<Error> for CQLiteParseError {
106 fn from(err: Error) -> Self {
107 CQLiteParseError::ParseError(err.to_string())
108 }
109}
110
111pub type ParseResult<T> = std::result::Result<T, CQLiteParseError>;
113
114pub fn parse_binary_data(data: &[u8]) -> ParseResult<Vec<u8>> {
116 if data.is_empty() {
117 return Err(CQLiteParseError::InvalidFormat("Empty input".to_string()));
118 }
119
120 Ok(data.to_vec())
123}
124
125pub fn parse_vint_binary(data: &[u8]) -> ParseResult<(u64, usize)> {
127 if data.is_empty() {
128 return Err(CQLiteParseError::InvalidFormat(
129 "Empty vint data".to_string(),
130 ));
131 }
132
133 let first_byte = data[0];
135 if first_byte & 0x80 == 0 {
136 Ok((first_byte as u64, 1))
138 } else {
139 Err(CQLiteParseError::Unsupported(
141 "Multi-byte vint not implemented".to_string(),
142 ))
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_binary_parser_creation() {
152 let config = ParserConfig::default();
153 let parser = SSTableParser::new(config).unwrap();
154
155 let info = parser.backend_info();
156 assert_eq!(info.name, "binary");
157 }
158
159 #[tokio::test]
160 async fn test_binary_parser_unsupported() {
161 let config = ParserConfig::default();
162 let parser = SSTableParser::new(config).unwrap();
163
164 let result = parser.parse("SELECT * FROM test").await;
165 assert!(result.is_err());
166 }
167
168 #[test]
169 fn test_parse_binary_data() {
170 let data = b"test data";
171 let result = parse_binary_data(data).unwrap();
172 assert_eq!(result, data);
173
174 let empty_result = parse_binary_data(&[]);
175 assert!(empty_result.is_err());
176 }
177
178 #[test]
179 fn test_parse_vint_binary() {
180 let data = &[0x42]; let (value, consumed) = parse_vint_binary(data).unwrap();
182 assert_eq!(value, 0x42);
183 assert_eq!(consumed, 1);
184
185 let empty_result = parse_vint_binary(&[]);
186 assert!(empty_result.is_err());
187 }
188
189 #[test]
190 fn test_parse_vint_binary_unsupported_multi_byte() {
191 let data = &[0x80, 0x01];
192 let err =
193 parse_vint_binary(data).expect_err("multi-byte vint should return unsupported error");
194 assert!(matches!(err, CQLiteParseError::Unsupported(_)));
195 }
196
197 #[test]
198 fn test_backend_info_and_validate_syntax() {
199 let info = SSTableParser::backend_info();
200 assert_eq!(info.name, "binary");
201 assert!(info.features.contains(&ParserFeature::Streaming));
202
203 let parser = SSTableParser::new(ParserConfig::default()).unwrap();
204 assert!(!parser.validate_syntax("SELECT * FROM ks.table"));
205 }
206}