Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-cpython/src/filepatterns.rs @ 42453:9609430d3625
rust-filepatterns: use bytes instead of String
In my initial patch, I introduced an unnecessary hard constraint on UTF-8
filenames and patterns which I forgot to remove. Although the performance
penalty for using String might be negligible, we don't want to break
compatibility with non-UTF-8 encodings for no reason.
Moreover, this change allows for a cleaner Rust core API.
This patch introduces a new utils module that is used with this fix.
Finally, PatternError was not put inside the Python module generated by
Rust, which would have raised a NameError.
Differential Revision: https://phab.mercurial-scm.org/D6485
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 06 Jun 2019 15:30:56 +0200 |
parents | 94f3a73b6672 |
children | 326fdce22fb2 |
line wrap: on
line diff
--- a/rust/hg-cpython/src/filepatterns.rs Sat Jun 01 01:24:49 2019 +0200 +++ b/rust/hg-cpython/src/filepatterns.rs Thu Jun 06 15:30:56 2019 +0200 @@ -11,14 +11,10 @@ //! and can be used as replacement for the the pure `filepatterns` Python module. //! use cpython::{ - exc, PyDict, PyErr, PyModule, PyResult, PyString, PyTuple, Python, - ToPyObject, + PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject, }; -use hg::{build_single_regex, read_pattern_file, PatternTuple}; -use exceptions::{ - PatternError, - PatternFileError, -}; +use exceptions::{PatternError, PatternFileError}; +use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple}; /// Rust does not like functions with different return signatures. /// The 3-tuple version is always returned by the hg-core function, @@ -32,17 +28,22 @@ /// for more details. fn read_pattern_file_wrapper( py: Python, - file_path: String, + file_path: PyObject, warn: bool, source_info: bool, ) -> PyResult<PyTuple> { - match read_pattern_file(file_path, warn) { + match read_pattern_file(file_path.extract::<PyBytes>(py)?.data(py), warn) { Ok((patterns, warnings)) => { if source_info { - return Ok((patterns, warnings).to_py_object(py)); + 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)); } - let itemgetter = |x: &PatternTuple| x.0.to_py_object(py); - let results: Vec<PyString> = + let itemgetter = |x: &PatternTuple| PyBytes::new(py, &x.0); + let results: Vec<PyBytes> = patterns.iter().map(itemgetter).collect(); Ok((results, warnings).to_py_object(py)) } @@ -52,22 +53,16 @@ fn build_single_regex_wrapper( py: Python, - kind: String, - pat: String, - globsuffix: String, -) -> PyResult<PyString> { + kind: PyObject, + pat: PyObject, + globsuffix: PyObject, +) -> PyResult<PyBytes> { match build_single_regex( - kind.as_ref(), - pat.as_bytes(), - globsuffix.as_bytes(), + kind.extract::<PyBytes>(py)?.data(py), + pat.extract::<PyBytes>(py)?.data(py), + globsuffix.extract::<PyBytes>(py)?.data(py), ) { - Ok(regex) => match String::from_utf8(regex) { - Ok(regex) => Ok(regex.to_py_object(py)), - Err(e) => Err(PyErr::new::<exc::UnicodeDecodeError, _>( - py, - e.to_string(), - )), - }, + Ok(regex) => Ok(PyBytes::new(py, ®ex)), Err(e) => Err(PatternError::pynew(py, e)), } } @@ -88,9 +83,9 @@ py_fn!( py, build_single_regex_wrapper( - kind: String, - pat: String, - globsuffix: String + kind: PyObject, + pat: PyObject, + globsuffix: PyObject ) ), )?; @@ -100,13 +95,13 @@ py_fn!( py, read_pattern_file_wrapper( - file_path: String, + file_path: PyObject, warn: bool, source_info: bool ) ), )?; - + m.add(py, "PatternError", py.get_type::<PatternError>())?; let sys = PyModule::import(py, "sys")?; let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?; sys_modules.set_item(py, dotted_name, &m)?;