##// END OF EJS Templates
rust-cpython: import utils::files::* function at module level...
Yuya Nishihara -
r44210:f79377f2 default
parent child Browse files
Show More
@@ -1,136 +1,134 b''
1 1 // filepatterns.rs
2 2 //
3 3 // Copyright 2019, Georges Racinet <gracinet@anybox.fr>,
4 4 // Raphaël Gomès <rgomes@octobus.net>
5 5 //
6 6 // This software may be used and distributed according to the terms of the
7 7 // GNU General Public License version 2 or any later version.
8 8
9 9 //! Bindings for the `hg::filepatterns` module provided by the
10 10 //! `hg-core` crate. From Python, this will be seen as `rustext.filepatterns`
11 11 //! and can be used as replacement for the the pure `filepatterns` Python
12 12 //! module.
13 13 //!
14 14 use crate::exceptions::{PatternError, PatternFileError};
15 15 use cpython::{
16 16 PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject,
17 17 };
18 use hg::{
19 build_single_regex, read_pattern_file, utils::files::get_path_from_bytes,
20 LineNumber, PatternTuple,
21 };
18 use hg::utils::files;
19 use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple};
22 20 use std::path::PathBuf;
23 21
24 22 /// Rust does not like functions with different return signatures.
25 23 /// The 3-tuple version is always returned by the hg-core function,
26 24 /// the (potential) conversion is handled at this level since it is not likely
27 25 /// to have any measurable impact on performance.
28 26 ///
29 27 /// The Python implementation passes a function reference for `warn` instead
30 28 /// of a boolean that is used to emit warnings while parsing. The Rust
31 29 /// implementation chooses to accumulate the warnings and propagate them to
32 30 /// Python upon completion. See the `readpatternfile` function in `match.py`
33 31 /// for more details.
34 32 fn read_pattern_file_wrapper(
35 33 py: Python,
36 34 file_path: PyObject,
37 35 warn: bool,
38 36 source_info: bool,
39 37 ) -> PyResult<PyTuple> {
40 38 let bytes = file_path.extract::<PyBytes>(py)?;
41 let path = get_path_from_bytes(bytes.data(py));
39 let path = files::get_path_from_bytes(bytes.data(py));
42 40 match read_pattern_file(path, warn) {
43 41 Ok((patterns, warnings)) => {
44 42 if source_info {
45 43 let itemgetter = |x: &PatternTuple| {
46 44 (PyBytes::new(py, &x.0), x.1, PyBytes::new(py, &x.2))
47 45 };
48 46 let results: Vec<(PyBytes, LineNumber, PyBytes)> =
49 47 patterns.iter().map(itemgetter).collect();
50 48 return Ok((results, warnings_to_py_bytes(py, &warnings))
51 49 .to_py_object(py));
52 50 }
53 51 let itemgetter = |x: &PatternTuple| PyBytes::new(py, &x.0);
54 52 let results: Vec<PyBytes> =
55 53 patterns.iter().map(itemgetter).collect();
56 54 Ok(
57 55 (results, warnings_to_py_bytes(py, &warnings))
58 56 .to_py_object(py),
59 57 )
60 58 }
61 59 Err(e) => Err(PatternFileError::pynew(py, e)),
62 60 }
63 61 }
64 62
65 63 fn warnings_to_py_bytes(
66 64 py: Python,
67 65 warnings: &[(PathBuf, Vec<u8>)],
68 66 ) -> Vec<(PyBytes, PyBytes)> {
69 67 warnings
70 68 .iter()
71 69 .map(|(path, syn)| {
72 70 (
73 71 PyBytes::new(py, &path.to_string_lossy().as_bytes()),
74 72 PyBytes::new(py, syn),
75 73 )
76 74 })
77 75 .collect()
78 76 }
79 77
80 78 fn build_single_regex_wrapper(
81 79 py: Python,
82 80 kind: PyObject,
83 81 pat: PyObject,
84 82 globsuffix: PyObject,
85 83 ) -> PyResult<PyBytes> {
86 84 match build_single_regex(
87 85 kind.extract::<PyBytes>(py)?.data(py),
88 86 pat.extract::<PyBytes>(py)?.data(py),
89 87 globsuffix.extract::<PyBytes>(py)?.data(py),
90 88 ) {
91 89 Ok(regex) => Ok(PyBytes::new(py, &regex)),
92 90 Err(e) => Err(PatternError::pynew(py, e)),
93 91 }
94 92 }
95 93
96 94 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
97 95 let dotted_name = &format!("{}.filepatterns", package);
98 96 let m = PyModule::new(py, dotted_name)?;
99 97
100 98 m.add(py, "__package__", package)?;
101 99 m.add(
102 100 py,
103 101 "__doc__",
104 102 "Patterns files parsing - Rust implementation",
105 103 )?;
106 104 m.add(
107 105 py,
108 106 "build_single_regex",
109 107 py_fn!(
110 108 py,
111 109 build_single_regex_wrapper(
112 110 kind: PyObject,
113 111 pat: PyObject,
114 112 globsuffix: PyObject
115 113 )
116 114 ),
117 115 )?;
118 116 m.add(
119 117 py,
120 118 "read_pattern_file",
121 119 py_fn!(
122 120 py,
123 121 read_pattern_file_wrapper(
124 122 file_path: PyObject,
125 123 warn: bool,
126 124 source_info: bool
127 125 )
128 126 ),
129 127 )?;
130 128 m.add(py, "PatternError", py.get_type::<PatternError>())?;
131 129 let sys = PyModule::import(py, "sys")?;
132 130 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
133 131 sys_modules.set_item(py, dotted_name, &m)?;
134 132
135 133 Ok(m)
136 134 }
General Comments 0
You need to be logged in to leave comments. Login now