rust/hg-cpython/src/utils.rs
changeset 52042 28a0eb21ff04
parent 49631 c7fb9b74e753
child 52046 de317a87ea6a
equal deleted inserted replaced
52041:652149ed64f0 52042:28a0eb21ff04
     1 use cpython::exc::ValueError;
     1 use cpython::exc::ValueError;
     2 use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python};
     2 use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python};
       
     3 use hg::config::Config;
       
     4 use hg::errors::HgError;
       
     5 use hg::repo::{Repo, RepoError};
     3 use hg::revlog::Node;
     6 use hg::revlog::Node;
       
     7 use hg::utils::files::get_path_from_bytes;
       
     8 
       
     9 use crate::exceptions::FallbackError;
     4 
    10 
     5 #[allow(unused)]
    11 #[allow(unused)]
     6 pub fn print_python_trace(py: Python) -> PyResult<PyObject> {
    12 pub fn print_python_trace(py: Python) -> PyResult<PyObject> {
     7     eprintln!("===============================");
    13     eprintln!("===============================");
     8     eprintln!("Printing Python stack from Rust");
    14     eprintln!("Printing Python stack from Rust");
    10     let traceback = py.import("traceback")?;
    16     let traceback = py.import("traceback")?;
    11     let sys = py.import("sys")?;
    17     let sys = py.import("sys")?;
    12     let kwargs = PyDict::new(py);
    18     let kwargs = PyDict::new(py);
    13     kwargs.set_item(py, "file", sys.get(py, "stderr")?)?;
    19     kwargs.set_item(py, "file", sys.get(py, "stderr")?)?;
    14     traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some(&kwargs))
    20     traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some(&kwargs))
       
    21 }
       
    22 
       
    23 pub fn hgerror_to_pyerr<T>(
       
    24     py: Python,
       
    25     error: Result<T, HgError>,
       
    26 ) -> PyResult<T> {
       
    27     error.map_err(|e| match e {
       
    28         HgError::IoError { .. } => {
       
    29             PyErr::new::<cpython::exc::IOError, _>(py, e.to_string())
       
    30         }
       
    31         HgError::UnsupportedFeature(e) => {
       
    32             let as_string = e.to_string();
       
    33             log::trace!("Update from null fallback: {}", as_string);
       
    34             PyErr::new::<FallbackError, _>(py, &as_string)
       
    35         }
       
    36         HgError::RaceDetected(_) => {
       
    37             unreachable!("must not surface to the user")
       
    38         }
       
    39         e => PyErr::new::<cpython::exc::RuntimeError, _>(py, e.to_string()),
       
    40     })
       
    41 }
       
    42 
       
    43 pub fn repo_error_to_pyerr<T>(
       
    44     py: Python,
       
    45     error: Result<T, RepoError>,
       
    46 ) -> PyResult<T> {
       
    47     hgerror_to_pyerr(py, error.map_err(HgError::from))
       
    48 }
       
    49 
       
    50 /// Get a repository from a given [`PyObject`] path, and bubble up any error
       
    51 /// that comes up.
       
    52 pub fn repo_from_path(py: Python, repo_path: PyObject) -> Result<Repo, PyErr> {
       
    53     let config =
       
    54         hgerror_to_pyerr(py, Config::load_non_repo().map_err(HgError::from))?;
       
    55     let py_bytes = &repo_path.extract::<PyBytes>(py)?;
       
    56     let repo_path = py_bytes.data(py);
       
    57     let repo = repo_error_to_pyerr(
       
    58         py,
       
    59         Repo::find(&config, Some(get_path_from_bytes(repo_path).to_owned())),
       
    60     )?;
       
    61     Ok(repo)
    15 }
    62 }
    16 
    63 
    17 // Necessary evil for the time being, could maybe be moved to
    64 // Necessary evil for the time being, could maybe be moved to
    18 // a TryFrom in Node itself
    65 // a TryFrom in Node itself
    19 const NODE_BYTES_LENGTH: usize = 20;
    66 const NODE_BYTES_LENGTH: usize = 20;