1#![allow(
9 clippy::cast_possible_wrap,
10 clippy::cast_possible_truncation,
11 clippy::cast_lossless
12)]
13
14use log::debug;
15use std::os::raw::{c_char, c_long, c_void};
16
17use crate::err::{ReadStatCError, ReadStatError, check_c_error};
18
19pub(crate) struct ReadStatParser {
24 parser: *mut readstat_sys::readstat_parser_t,
25}
26
27impl ReadStatParser {
28 pub(crate) fn new() -> Result<Self, ReadStatError> {
38 let parser: *mut readstat_sys::readstat_parser_t =
39 unsafe { readstat_sys::readstat_parser_init() };
40
41 if parser.is_null() {
42 return Err(ReadStatError::CLibrary(
43 ReadStatCError::READSTAT_ERROR_MALLOC,
44 ));
45 }
46
47 Ok(Self { parser })
48 }
49
50 pub(crate) fn set_metadata_handler(
52 self,
53 metadata_handler: readstat_sys::readstat_metadata_handler,
54 ) -> Result<Self, ReadStatError> {
55 let set_metadata_handler_error =
56 unsafe { readstat_sys::readstat_set_metadata_handler(self.parser, metadata_handler) };
57
58 debug!("After setting metadata handler, error ==> {set_metadata_handler_error}");
59
60 check_c_error(set_metadata_handler_error as i32)?;
61 Ok(self)
62 }
63
64 pub(crate) fn set_row_limit(self, row_limit: Option<u32>) -> Result<Self, ReadStatError> {
66 if let Some(r) = row_limit {
67 let set_row_limit_error =
68 unsafe { readstat_sys::readstat_set_row_limit(self.parser, r as c_long) };
69
70 debug!("After setting row limit, error ==> {set_row_limit_error}");
71
72 check_c_error(set_row_limit_error as i32)?;
73 }
74 Ok(self)
75 }
76
77 pub(crate) fn set_row_offset(self, row_offset: Option<u32>) -> Result<Self, ReadStatError> {
79 if let Some(r) = row_offset {
80 let set_row_offset_error =
81 unsafe { readstat_sys::readstat_set_row_offset(self.parser, r as c_long) };
82
83 debug!("After setting row offset, error ==> {set_row_offset_error}");
84
85 check_c_error(set_row_offset_error as i32)?;
86 }
87 Ok(self)
88 }
89
90 pub(crate) fn set_variable_handler(
92 self,
93 variable_handler: readstat_sys::readstat_variable_handler,
94 ) -> Result<Self, ReadStatError> {
95 let set_variable_handler_error =
96 unsafe { readstat_sys::readstat_set_variable_handler(self.parser, variable_handler) };
97
98 debug!("After setting variable handler, error ==> {set_variable_handler_error}");
99
100 check_c_error(set_variable_handler_error as i32)?;
101 Ok(self)
102 }
103
104 pub(crate) fn set_value_handler(
106 self,
107 value_handler: readstat_sys::readstat_value_handler,
108 ) -> Result<Self, ReadStatError> {
109 let set_value_handler_error =
110 unsafe { readstat_sys::readstat_set_value_handler(self.parser, value_handler) };
111
112 debug!("After setting value handler, error ==> {set_value_handler_error}");
113
114 check_c_error(set_value_handler_error as i32)?;
115 Ok(self)
116 }
117
118 pub(crate) fn set_open_handler(
120 self,
121 open_handler: readstat_sys::readstat_open_handler,
122 ) -> Result<Self, ReadStatError> {
123 let error = unsafe { readstat_sys::readstat_set_open_handler(self.parser, open_handler) };
124 debug!("After setting open handler, error ==> {error}");
125 check_c_error(error as i32)?;
126 Ok(self)
127 }
128
129 pub(crate) fn set_close_handler(
131 self,
132 close_handler: readstat_sys::readstat_close_handler,
133 ) -> Result<Self, ReadStatError> {
134 let error = unsafe { readstat_sys::readstat_set_close_handler(self.parser, close_handler) };
135 debug!("After setting close handler, error ==> {error}");
136 check_c_error(error as i32)?;
137 Ok(self)
138 }
139
140 pub(crate) fn set_seek_handler(
142 self,
143 seek_handler: readstat_sys::readstat_seek_handler,
144 ) -> Result<Self, ReadStatError> {
145 let error = unsafe { readstat_sys::readstat_set_seek_handler(self.parser, seek_handler) };
146 debug!("After setting seek handler, error ==> {error}");
147 check_c_error(error as i32)?;
148 Ok(self)
149 }
150
151 pub(crate) fn set_read_handler(
153 self,
154 read_handler: readstat_sys::readstat_read_handler,
155 ) -> Result<Self, ReadStatError> {
156 let error = unsafe { readstat_sys::readstat_set_read_handler(self.parser, read_handler) };
157 debug!("After setting read handler, error ==> {error}");
158 check_c_error(error as i32)?;
159 Ok(self)
160 }
161
162 pub(crate) fn set_update_handler(
164 self,
165 update_handler: readstat_sys::readstat_update_handler,
166 ) -> Result<Self, ReadStatError> {
167 let error =
168 unsafe { readstat_sys::readstat_set_update_handler(self.parser, update_handler) };
169 debug!("After setting update handler, error ==> {error}");
170 check_c_error(error as i32)?;
171 Ok(self)
172 }
173
174 pub(crate) fn set_io_ctx(self, io_ctx: *mut c_void) -> Result<Self, ReadStatError> {
176 let error = unsafe { readstat_sys::readstat_set_io_ctx(self.parser, io_ctx) };
177 debug!("After setting io ctx, error ==> {error}");
178 check_c_error(error as i32)?;
179 Ok(self)
180 }
181
182 pub(crate) fn parse_sas7bdat(
187 &mut self,
188 path: *const c_char,
189 user_ctx: *mut c_void,
190 ) -> readstat_sys::readstat_error_t {
191 let parse_sas7bdat_error: readstat_sys::readstat_error_t =
192 unsafe { readstat_sys::readstat_parse_sas7bdat(self.parser, path, user_ctx) };
193
194 debug!("After calling parse sas7bdat, error ==> {parse_sas7bdat_error}");
195
196 parse_sas7bdat_error
197 }
198}
199
200impl Drop for ReadStatParser {
201 fn drop(&mut self) {
202 debug!("Freeing parser");
203
204 unsafe { readstat_sys::readstat_parser_free(self.parser) };
205 }
206}