##// END OF EJS Templates
rust-nodemap: add binding for `nodemap_data_all`...
rust-nodemap: add binding for `nodemap_data_all` Differential Revision: https://phab.mercurial-scm.org/D8158

File last commit:

r44779:cf1f8660 default
r44995:b581231a default
Show More
dirstate.rs
133 lines | 4.2 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 // dirstate.rs
//
// Copyright 2019 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::dirstate` module provided by the
//! `hg-core` package.
//!
//! From Python, this will be seen as `mercurial.rustext.dirstate`
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 mod copymap;
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 mod dirs_multiset;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 mod dirstate_map;
Raphaël Gomès
rust-dirstatemap: add `NonNormalEntries` class...
r44779 mod non_normal_entries;
Raphaël Gomès
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
r43567 mod status;
use crate::dirstate::{
dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
};
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 use cpython::{
Raphaël Gomès
rust-status: remove dead code...
r43761 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
Python,
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 };
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 use hg::{
utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
StateMap,
};
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 use libc::{c_char, c_int};
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 use std::convert::TryFrom;
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489
Yuya Nishihara
rust-cpython: turn inline comments into non-doc comments
r43482 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
// for this type, and raises a Python `Exception` if the check does not pass.
// Because this type differs only in name from the regular Python tuple, it
// would be a good idea in the near future to remove it entirely to allow
// for a pure Python tuple of the same effective structure to be used,
// rendering this type and the capsule below useless.
Yuya Nishihara
rust-cpython: leverage upstreamed py_capsule_fn!() macro
r43484 py_capsule_fn!(
from mercurial.cext.parsers import make_dirstate_tuple_CAPI
as make_dirstate_tuple_capi
signature (
state: c_char,
mode: c_int,
size: c_int,
mtime: c_int,
) -> *mut RawPyObject
);
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479 pub fn make_dirstate_tuple(
py: Python,
entry: &DirstateEntry,
) -> PyResult<PyObject> {
Yuya Nishihara
rust-cpython: leverage upstreamed py_capsule_fn!() macro
r43484 // might be silly to retrieve capsule function in hot loop
let make = make_dirstate_tuple_capi::retrieve(py)?;
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479
let &DirstateEntry {
state,
mode,
size,
mtime,
} = entry;
// Explicitly go through u8 first, then cast to platform-specific `c_char`
// because Into<u8> has a specific implementation while `as c_char` would
// just do a naive enum cast.
let state_code: u8 = state.into();
Yuya Nishihara
rust-cpython: mark capsule function as unsafe
r43480
Yuya Nishihara
rust-cpython: fix signature of make_dirstate_tuple()...
r43481 let maybe_obj = unsafe {
Yuya Nishihara
rust-cpython: mark capsule function as unsafe
r43480 let ptr = make(state_code as c_char, mode, size, mtime);
Yuya Nishihara
rust-cpython: fix signature of make_dirstate_tuple()...
r43481 PyObject::from_owned_ptr_opt(py, ptr)
};
maybe_obj.ok_or_else(|| PyErr::fetch(py))
Yuya Nishihara
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()...
r43479 }
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
Raphaël Gomès
rust-dirstate: add "dirs" rust-cpython binding...
r42737 dmap.items(py)
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 .iter()
.map(|(filename, stats)| {
let stats = stats.extract::<PySequence>(py)?;
let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 let state = EntryState::try_from(state.data(py)[0]).map_err(
|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
},
)?;
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 let mode = stats.get_item(py, 1)?.extract(py)?;
let size = stats.get_item(py, 2)?.extract(py)?;
let mtime = stats.get_item(py, 3)?.extract(py)?;
let filename = filename.extract::<PyBytes>(py)?;
let filename = filename.data(py);
Ok((
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from(filename.to_owned()),
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 DirstateEntry {
state,
mode,
size,
mtime,
},
))
})
Raphaël Gomès
rust-dirstate: add "dirs" rust-cpython binding...
r42737 .collect()
}
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 /// Create the module, with `__package__` given from parent
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.dirstate", package);
let m = PyModule::new(py, dotted_name)?;
Raphaël Gomès
rust-dirstate: add "dirs" rust-cpython binding...
r42737
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 m.add(py, "__package__", package)?;
m.add(py, "__doc__", "Dirstate - Rust implementation")?;
Raphaël Gomès
rust-dirstate: add "dirs" rust-cpython binding...
r42737 m.add_class::<Dirs>(py)?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 m.add_class::<DirstateMap>(py)?;
Raphaël Gomès
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
r43567 m.add(
py,
"status",
py_fn!(
py,
status_wrapper(
dmap: DirstateMap,
root_dir: PyObject,
Raphaël Gomès
rust-dirstate-status: update bridge for new rust version of `dirstate.status`...
r44368 matcher: PyObject,
Raphaël Gomès
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
r43567 list_clean: bool,
last_normal_time: i64,
check_exec: bool
)
),
)?;
Raphaël Gomès
rust-dirstate: add "dirs" rust-cpython binding...
r42737
Raphaël Gomès
rust-dirstate: add rust-cpython bindings to the new parse/pack functions...
r42489 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)
}