Mercurial > public > mercurial-scm > hg
diff rust/hg-cpython/src/dirstate.rs @ 42747:760a7851e9ba
rust-parsers: move parser bindings to their own file and Python module
This tidies up the Rust side while simplifying the Python side.
Differential Revision: https://phab.mercurial-scm.org/D6627
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 10 Jul 2019 10:16:28 +0200 |
parents | b3518b0baa47 |
children | 7cae6bc29ff9 |
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate.rs Mon Jul 08 18:01:39 2019 +0200 +++ b/rust/hg-cpython/src/dirstate.rs Wed Jul 10 10:16:28 2019 +0200 @@ -12,19 +12,14 @@ mod dirs_multiset; use crate::dirstate::dirs_multiset::Dirs; use cpython::{ - exc, PyBytes, PyDict, PyErr, PyInt, PyModule, PyObject, PyResult, - PySequence, PyTuple, Python, PythonObject, ToPyObject, + PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence, Python, }; -use hg::{ - pack_dirstate, parse_dirstate, CopyVecEntry, DirstateEntry, - DirstatePackError, DirstateParents, DirstateParseError, DirstateVec, -}; +use hg::{DirstateEntry, DirstateVec}; use libc::{c_char, c_int}; #[cfg(feature = "python27")] use python27_sys::PyCapsule_Import; #[cfg(feature = "python3")] use python3_sys::PyCapsule_Import; -use std::collections::HashMap; use std::ffi::CStr; use std::mem::transmute; @@ -44,7 +39,9 @@ /// This is largely a copy/paste from cindex.rs, pending the merge of a /// `py_capsule_fn!` macro in the rust-cpython project: /// https://github.com/dgrunwald/rust-cpython/pull/169 -fn decapsule_make_dirstate_tuple(py: Python) -> PyResult<MakeDirstateTupleFn> { +pub fn decapsule_make_dirstate_tuple( + py: Python, +) -> PyResult<MakeDirstateTupleFn> { unsafe { let caps_name = CStr::from_bytes_with_nul_unchecked( b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0", @@ -57,52 +54,7 @@ } } -fn parse_dirstate_wrapper( - py: Python, - dmap: PyDict, - copymap: PyDict, - st: PyBytes, -) -> PyResult<PyTuple> { - match parse_dirstate(st.data(py)) { - Ok((parents, dirstate_vec, copies)) => { - for (filename, entry) in dirstate_vec { - dmap.set_item( - py, - PyBytes::new(py, &filename[..]), - decapsule_make_dirstate_tuple(py)?( - entry.state as c_char, - entry.mode, - entry.size, - entry.mtime, - ), - )?; - } - for CopyVecEntry { path, copy_path } in copies { - copymap.set_item( - py, - PyBytes::new(py, path), - PyBytes::new(py, copy_path), - )?; - } - Ok((PyBytes::new(py, parents.p1), PyBytes::new(py, parents.p2)) - .to_py_object(py)) - } - Err(e) => Err(PyErr::new::<exc::ValueError, _>( - py, - match e { - DirstateParseError::TooLittleData => { - "too little data for parents".to_string() - } - DirstateParseError::Overflow => { - "overflow in dirstate".to_string() - } - DirstateParseError::CorruptedEntry(e) => e, - }, - )), - } -} - -fn extract_dirstate_vec( +pub fn extract_dirstate_vec( py: Python, dmap: &PyDict, ) -> Result<DirstateVec, PyErr> { @@ -130,76 +82,6 @@ .collect() } -fn pack_dirstate_wrapper( - py: Python, - dmap: PyDict, - copymap: PyDict, - pl: PyTuple, - now: PyInt, -) -> PyResult<PyBytes> { - let p1 = pl.get_item(py, 0).extract::<PyBytes>(py)?; - let p1: &[u8] = p1.data(py); - let p2 = pl.get_item(py, 1).extract::<PyBytes>(py)?; - let p2: &[u8] = p2.data(py); - - let dirstate_vec = extract_dirstate_vec(py, &dmap)?; - - let copies: Result<HashMap<Vec<u8>, Vec<u8>>, PyErr> = copymap - .items(py) - .iter() - .map(|(key, value)| { - Ok(( - key.extract::<PyBytes>(py)?.data(py).to_owned(), - value.extract::<PyBytes>(py)?.data(py).to_owned(), - )) - }) - .collect(); - - match pack_dirstate( - &dirstate_vec, - &copies?, - DirstateParents { p1, p2 }, - now.as_object().extract::<i32>(py)?, - ) { - Ok((packed, new_dirstate_vec)) => { - for ( - filename, - DirstateEntry { - state, - mode, - size, - mtime, - }, - ) in new_dirstate_vec - { - dmap.set_item( - py, - PyBytes::new(py, &filename[..]), - decapsule_make_dirstate_tuple(py)?( - state as c_char, - mode, - size, - mtime, - ), - )?; - } - Ok(PyBytes::new(py, &packed)) - } - Err(error) => Err(PyErr::new::<exc::ValueError, _>( - py, - match error { - DirstatePackError::CorruptedParent => { - "expected a 20-byte hash".to_string() - } - DirstatePackError::CorruptedEntry(e) => e, - DirstatePackError::BadSize(expected, actual) => { - format!("bad dirstate size: {} != {}", actual, expected) - } - }, - )), - } -} - /// Create the module, with `__package__` given from parent pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { let dotted_name = &format!("{}.dirstate", package); @@ -207,27 +89,6 @@ m.add(py, "__package__", package)?; m.add(py, "__doc__", "Dirstate - Rust implementation")?; - m.add( - py, - "parse_dirstate", - py_fn!( - py, - parse_dirstate_wrapper(dmap: PyDict, copymap: PyDict, st: PyBytes) - ), - )?; - m.add( - py, - "pack_dirstate", - py_fn!( - py, - pack_dirstate_wrapper( - dmap: PyDict, - copymap: PyDict, - pl: PyTuple, - now: PyInt - ) - ), - )?; m.add_class::<Dirs>(py)?;