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 )),