Mercurial > hg
comparison rust/hg-cpython/src/dirstate/status.rs @ 49346:75119bbee3d1
hg-cpython: refactor matcher transformation logic
This reduces duplication and will allow for recursive transformation in
UnionMatcher.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 08 Jun 2022 15:30:58 +0200 |
parents | 137d6bb71937 |
children | 0043c7aa3250 |
comparison
equal
deleted
inserted
replaced
49345:137d6bb71937 | 49346:75119bbee3d1 |
---|---|
13 use cpython::{ | 13 use cpython::{ |
14 exc::ValueError, ObjectProtocol, PyBytes, PyErr, PyList, PyObject, | 14 exc::ValueError, ObjectProtocol, PyBytes, PyErr, PyList, PyObject, |
15 PyResult, PyTuple, Python, PythonObject, ToPyObject, | 15 PyResult, PyTuple, Python, PythonObject, ToPyObject, |
16 }; | 16 }; |
17 use hg::dirstate::status::StatusPath; | 17 use hg::dirstate::status::StatusPath; |
18 use hg::matchers::Matcher; | |
18 use hg::{ | 19 use hg::{ |
19 matchers::{AlwaysMatcher, FileMatcher, IncludeMatcher}, | 20 matchers::{AlwaysMatcher, FileMatcher, IncludeMatcher}, |
20 parse_pattern_syntax, | 21 parse_pattern_syntax, |
21 utils::{ | 22 utils::{ |
22 files::{get_bytes_from_path, get_path_from_bytes}, | 23 files::{get_bytes_from_path, get_path_from_bytes}, |
131 let (status_res, warnings) = | 132 let (status_res, warnings) = |
132 res.map_err(|e| handle_fallback(py, e))?; | 133 res.map_err(|e| handle_fallback(py, e))?; |
133 build_response(py, status_res, warnings) | 134 build_response(py, status_res, warnings) |
134 }; | 135 }; |
135 | 136 |
137 let matcher = extract_matcher(py, matcher)?; | |
138 dmap.with_status( | |
139 &*matcher, | |
140 root_dir.to_path_buf(), | |
141 ignore_files, | |
142 StatusOptions { | |
143 check_exec, | |
144 list_clean, | |
145 list_ignored, | |
146 list_unknown, | |
147 list_copies, | |
148 collect_traversed_dirs, | |
149 }, | |
150 after_status, | |
151 ) | |
152 } | |
153 | |
154 /// Transform a Python matcher into a Rust matcher. | |
155 fn extract_matcher( | |
156 py: Python, | |
157 matcher: PyObject, | |
158 ) -> PyResult<Box<dyn Matcher + Sync>> { | |
136 match matcher.get_type(py).name(py).borrow() { | 159 match matcher.get_type(py).name(py).borrow() { |
137 "alwaysmatcher" => { | 160 "alwaysmatcher" => Ok(Box::new(AlwaysMatcher)), |
138 let matcher = AlwaysMatcher; | |
139 dmap.with_status( | |
140 &matcher, | |
141 root_dir.to_path_buf(), | |
142 ignore_files, | |
143 StatusOptions { | |
144 check_exec, | |
145 list_clean, | |
146 list_ignored, | |
147 list_unknown, | |
148 list_copies, | |
149 collect_traversed_dirs, | |
150 }, | |
151 after_status, | |
152 ) | |
153 } | |
154 "exactmatcher" => { | 161 "exactmatcher" => { |
155 let files = matcher.call_method( | 162 let files = matcher.call_method( |
156 py, | 163 py, |
157 "files", | 164 "files", |
158 PyTuple::new(py, &[]), | 165 PyTuple::new(py, &[]), |
167 )) | 174 )) |
168 }) | 175 }) |
169 .collect(); | 176 .collect(); |
170 | 177 |
171 let files = files?; | 178 let files = files?; |
172 let matcher = FileMatcher::new(files) | 179 let file_matcher = FileMatcher::new(files) |
173 .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?; | 180 .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?; |
174 dmap.with_status( | 181 Ok(Box::new(file_matcher)) |
175 &matcher, | |
176 root_dir.to_path_buf(), | |
177 ignore_files, | |
178 StatusOptions { | |
179 check_exec, | |
180 list_clean, | |
181 list_ignored, | |
182 list_unknown, | |
183 list_copies, | |
184 collect_traversed_dirs, | |
185 }, | |
186 after_status, | |
187 ) | |
188 } | 182 } |
189 "includematcher" => { | 183 "includematcher" => { |
190 // Get the patterns from Python even though most of them are | 184 // Get the patterns from Python even though most of them are |
191 // redundant with those we will parse later on, as they include | 185 // redundant with those we will parse later on, as they include |
192 // those passed from the command line. | 186 // those passed from the command line. |
219 let ignore_patterns = ignore_patterns?; | 213 let ignore_patterns = ignore_patterns?; |
220 | 214 |
221 let matcher = IncludeMatcher::new(ignore_patterns) | 215 let matcher = IncludeMatcher::new(ignore_patterns) |
222 .map_err(|e| handle_fallback(py, e.into()))?; | 216 .map_err(|e| handle_fallback(py, e.into()))?; |
223 | 217 |
224 dmap.with_status( | 218 Ok(Box::new(matcher)) |
225 &matcher, | |
226 root_dir.to_path_buf(), | |
227 ignore_files, | |
228 StatusOptions { | |
229 check_exec, | |
230 list_clean, | |
231 list_ignored, | |
232 list_unknown, | |
233 list_copies, | |
234 collect_traversed_dirs, | |
235 }, | |
236 after_status, | |
237 ) | |
238 } | 219 } |
239 e => Err(PyErr::new::<FallbackError, _>( | 220 e => Err(PyErr::new::<FallbackError, _>( |
240 py, | 221 py, |
241 format!("Unsupported matcher {}", e), | 222 format!("Unsupported matcher {}", e), |
242 )), | 223 )), |