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