filepatterns.rs
110 lines
| 3.7 KiB
| application/rls-services+xml
|
RustLexer
Raphaël Gomès
|
r42515 | // filepatterns.rs | ||
// | ||||
// Copyright 2019, Georges Racinet <gracinet@anybox.fr>, | ||||
// Raphaël Gomès <rgomes@octobus.net> | ||||
// | ||||
// This software may be used and distributed according to the terms of the | ||||
// GNU General Public License version 2 or any later version. | ||||
//! Bindings for the `hg::filepatterns` module provided by the | ||||
//! `hg-core` crate. From Python, this will be seen as `rustext.filepatterns` | ||||
//! and can be used as replacement for the the pure `filepatterns` Python module. | ||||
//! | ||||
use cpython::{ | ||||
Raphaël Gomès
|
r42630 | PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject, | ||
Raphaël Gomès
|
r42515 | }; | ||
Raphaël Gomès
|
r42630 | use exceptions::{PatternError, PatternFileError}; | ||
use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple}; | ||||
Raphaël Gomès
|
r42515 | |||
/// Rust does not like functions with different return signatures. | ||||
/// The 3-tuple version is always returned by the hg-core function, | ||||
/// the (potential) conversion is handled at this level since it is not likely | ||||
/// to have any measurable impact on performance. | ||||
/// | ||||
/// The Python implementation passes a function reference for `warn` instead | ||||
/// of a boolean that is used to emit warnings while parsing. The Rust | ||||
/// implementation chooses to accumulate the warnings and propagate them to | ||||
/// Python upon completion. See the `readpatternfile` function in `match.py` | ||||
/// for more details. | ||||
fn read_pattern_file_wrapper( | ||||
py: Python, | ||||
Raphaël Gomès
|
r42630 | file_path: PyObject, | ||
Raphaël Gomès
|
r42515 | warn: bool, | ||
source_info: bool, | ||||
) -> PyResult<PyTuple> { | ||||
Raphaël Gomès
|
r42630 | match read_pattern_file(file_path.extract::<PyBytes>(py)?.data(py), warn) { | ||
Raphaël Gomès
|
r42515 | Ok((patterns, warnings)) => { | ||
if source_info { | ||||
Raphaël Gomès
|
r42630 | let itemgetter = |x: &PatternTuple| { | ||
(PyBytes::new(py, &x.0), x.1, PyBytes::new(py, &x.2)) | ||||
}; | ||||
let results: Vec<(PyBytes, LineNumber, PyBytes)> = | ||||
patterns.iter().map(itemgetter).collect(); | ||||
return Ok((results, warnings).to_py_object(py)); | ||||
Raphaël Gomès
|
r42515 | } | ||
Raphaël Gomès
|
r42630 | let itemgetter = |x: &PatternTuple| PyBytes::new(py, &x.0); | ||
let results: Vec<PyBytes> = | ||||
Raphaël Gomès
|
r42515 | patterns.iter().map(itemgetter).collect(); | ||
Ok((results, warnings).to_py_object(py)) | ||||
} | ||||
Err(e) => Err(PatternFileError::pynew(py, e)), | ||||
} | ||||
} | ||||
fn build_single_regex_wrapper( | ||||
py: Python, | ||||
Raphaël Gomès
|
r42630 | kind: PyObject, | ||
pat: PyObject, | ||||
globsuffix: PyObject, | ||||
) -> PyResult<PyBytes> { | ||||
Raphaël Gomès
|
r42515 | match build_single_regex( | ||
Raphaël Gomès
|
r42630 | kind.extract::<PyBytes>(py)?.data(py), | ||
pat.extract::<PyBytes>(py)?.data(py), | ||||
globsuffix.extract::<PyBytes>(py)?.data(py), | ||||
Raphaël Gomès
|
r42515 | ) { | ||
Raphaël Gomès
|
r42630 | Ok(regex) => Ok(PyBytes::new(py, ®ex)), | ||
Raphaël Gomès
|
r42515 | Err(e) => Err(PatternError::pynew(py, e)), | ||
} | ||||
} | ||||
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { | ||||
let dotted_name = &format!("{}.filepatterns", package); | ||||
let m = PyModule::new(py, dotted_name)?; | ||||
m.add(py, "__package__", package)?; | ||||
m.add( | ||||
py, | ||||
"__doc__", | ||||
"Patterns files parsing - Rust implementation", | ||||
)?; | ||||
m.add( | ||||
py, | ||||
"build_single_regex", | ||||
py_fn!( | ||||
py, | ||||
build_single_regex_wrapper( | ||||
Raphaël Gomès
|
r42630 | kind: PyObject, | ||
pat: PyObject, | ||||
globsuffix: PyObject | ||||
Raphaël Gomès
|
r42515 | ) | ||
), | ||||
)?; | ||||
m.add( | ||||
py, | ||||
"read_pattern_file", | ||||
py_fn!( | ||||
py, | ||||
read_pattern_file_wrapper( | ||||
Raphaël Gomès
|
r42630 | file_path: PyObject, | ||
Raphaël Gomès
|
r42515 | warn: bool, | ||
source_info: bool | ||||
) | ||||
), | ||||
)?; | ||||
Raphaël Gomès
|
r42630 | m.add(py, "PatternError", py.get_type::<PatternError>())?; | ||
Raphaël Gomès
|
r42515 | let sys = PyModule::import(py, "sys")?; | ||
let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?; | ||||
sys_modules.set_item(py, dotted_name, &m)?; | ||||
Ok(m) | ||||
} | ||||