1#[cfg(feature = "python")]
76use pyo3::exceptions::PyValueError;
77#[cfg(feature = "python")]
78use pyo3::prelude::*;
79
80use std::io::Read;
81
82#[doc(hidden)]
83pub use types::{RdbError, RdbOk, RdbResult, Type};
84
85pub mod constants;
86pub mod decoder;
87pub mod filter;
88pub mod formatter;
89pub mod types;
90
91pub use decoder::RdbDecoder;
92pub use filter::{Filter, Simple};
93pub use formatter::{Formatter, FormatterType};
94
95pub struct RdbParser<R: Read, L: Filter, F: Formatter> {
97 decoder: RdbDecoder<R, L>,
98 formatter: Option<F>,
99}
100
101impl<R: Read, L: Filter, F: Formatter> RdbParser<R, L, F> {
102 pub fn builder() -> RdbParserBuilder<R, L, F> {
103 RdbParserBuilder {
104 reader: None,
105 filter: None,
106 formatter: None,
107 }
108 }
109
110 }
114
115#[derive(Default)]
116pub struct RdbParserBuilder<R: Read, L: Filter, F: Formatter> {
117 reader: Option<R>,
118 filter: Option<L>,
119 formatter: Option<F>,
120}
121
122impl<R: Read, L: Filter + Default, F: Formatter> RdbParserBuilder<R, L, F> {
123 pub fn build(self) -> RdbParser<R, L, F> {
124 let reader = self.reader.unwrap();
125 let filter = self.filter.unwrap_or_default();
126 let formatter = self.formatter;
127 RdbParser {
128 decoder: RdbDecoder::new(reader, filter).unwrap(),
129 formatter,
130 }
131 }
132
133 pub fn with_reader(mut self, reader: R) -> Self {
134 self.reader = Some(reader);
135 self
136 }
137
138 pub fn with_filter(mut self, filter: L) -> Self {
139 self.filter = Some(filter);
140 self
141 }
142
143 pub fn with_formatter(mut self, formatter: F) -> Self {
144 self.formatter = Some(formatter);
145 self
146 }
147}
148
149impl<R: Read, L: Filter, F: Formatter> RdbParser<R, L, F> {
150 pub fn parse(self) -> RdbResult<()> {
151 if let Some(mut formatter) = self.formatter {
152 formatter.start_rdb();
153 for value in self.decoder {
154 formatter.format(&value?)?;
155 }
156 formatter.end_rdb();
157 }
158 Ok(())
159 }
160}
161
162pub fn parse<R: Read, L: Filter + Default, F: Formatter>(
163 reader: R,
164 formatter: F,
165 filter: L,
166) -> RdbResult<()> {
167 let parser = RdbParser::builder()
168 .with_reader(reader)
169 .with_filter(filter)
170 .with_formatter(formatter)
171 .build();
172 parser.parse()
173}
174
175#[cfg(feature = "python")]
176#[pyclass(name = "RdbDecoder")]
177pub struct PyRdbDecoder {
178 decoder: RdbDecoder<std::fs::File, Simple>,
179}
180
181#[cfg(feature = "python")]
182#[pymethods]
183impl PyRdbDecoder {
184 #[new]
185 pub fn new(path: &str) -> PyResult<Self> {
186 let file = std::fs::File::open(path)
187 .map_err(|e| PyValueError::new_err(format!("Failed to open file: {}", e)))?;
188
189 let mut filter = Simple::new();
190
191 for t in [
192 Type::Hash,
193 Type::String,
194 Type::List,
195 Type::Set,
196 Type::SortedSet,
197 ] {
198 filter.add_type(t);
199 }
200
201 let decoder = RdbDecoder::new(file, filter)
202 .map_err(|e| PyValueError::new_err(format!("Failed to create decoder: {}", e)))?;
203
204 Ok(PyRdbDecoder { decoder })
205 }
206
207 fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
208 slf
209 }
210
211 fn __next__(mut slf: PyRefMut<'_, Self>) -> PyResult<Option<PyObject>> {
212 match slf.decoder.next() {
213 Some(Ok(value)) => Python::with_gil(|py| {
214 value
215 .into_pyobject(py)
216 .map(|obj| Some(obj.into()))
217 .map_err(|e| PyValueError::new_err(format!("Conversion error: {}", e)))
218 }),
219 Some(Err(e)) => Err(PyValueError::new_err(format!("Parsing error: {}", e))),
220 None => Ok(None),
221 }
222 }
223}
224
225#[cfg(feature = "python")]
226#[pymodule(name = "rdb")]
227fn rdb_py(m: &Bound<'_, PyModule>) -> PyResult<()> {
228 m.add_class::<PyRdbDecoder>()?;
229 Ok(())
230}