dirstate.rs
112 lines
| 3.4 KiB
| application/rls-services+xml
|
RustLexer
|
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` | ||||
|
r42999 | mod copymap; | ||
|
r42991 | mod dirs_multiset; | ||
|
r42999 | mod dirstate_map; | ||
|
r44779 | mod non_normal_entries; | ||
|
r43567 | mod status; | ||
|
r45016 | use crate::{ | ||
dirstate::{ | ||||
dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper, | ||||
}, | ||||
exceptions, | ||||
|
r43567 | }; | ||
|
r42489 | use cpython::{ | ||
|
r48833 | PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, Python, | ||
|
r42489 | }; | ||
|
r48055 | use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER; | ||
|
r48833 | use hg::DirstateEntry; | ||
|
r42828 | use libc::{c_char, c_int}; | ||
|
r42489 | |||
|
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. | ||||
|
r43484 | py_capsule_fn!( | ||
r48328 | from mercurial.cext.parsers import make_dirstate_item_CAPI | |||
as make_dirstate_item_capi | ||||
|
r43484 | signature ( | ||
state: c_char, | ||||
mode: c_int, | ||||
size: c_int, | ||||
mtime: c_int, | ||||
) -> *mut RawPyObject | ||||
); | ||||
|
r42489 | |||
r48328 | pub fn make_dirstate_item( | |||
|
r43479 | py: Python, | ||
entry: &DirstateEntry, | ||||
) -> PyResult<PyObject> { | ||||
// 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. | ||||
|
r48834 | let state_code: u8 = entry.state().into(); | ||
|
r43479 | |||
r48367 | let make = make_dirstate_item_capi::retrieve(py)?; | |||
let maybe_obj = unsafe { | ||||
|
r48837 | let ptr = make( | ||
state_code as c_char, | ||||
entry.mode(), | ||||
entry.size(), | ||||
entry.mtime(), | ||||
); | ||||
r48367 | PyObject::from_owned_ptr_opt(py, ptr) | |||
}; | ||||
maybe_obj.ok_or_else(|| PyErr::fetch(py)) | ||||
} | ||||
|
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)?; | ||||
|
r42737 | |||
|
r46090 | env_logger::init(); | ||
|
r45027 | |||
|
r42489 | m.add(py, "__package__", package)?; | ||
m.add(py, "__doc__", "Dirstate - Rust implementation")?; | ||||
|
r45016 | m.add( | ||
py, | ||||
"FallbackError", | ||||
py.get_type::<exceptions::FallbackError>(), | ||||
)?; | ||||
|
r42737 | m.add_class::<Dirs>(py)?; | ||
|
r42999 | m.add_class::<DirstateMap>(py)?; | ||
|
r48055 | m.add(py, "V2_FORMAT_MARKER", PyBytes::new(py, V2_FORMAT_MARKER))?; | ||
|
r43567 | m.add( | ||
py, | ||||
"status", | ||||
py_fn!( | ||||
py, | ||||
status_wrapper( | ||||
dmap: DirstateMap, | ||||
root_dir: PyObject, | ||||
|
r44368 | matcher: PyObject, | ||
|
r45016 | ignorefiles: PyList, | ||
check_exec: bool, | ||||
|
r43567 | last_normal_time: i64, | ||
|
r45016 | list_clean: bool, | ||
list_ignored: bool, | ||||
|
r45354 | list_unknown: bool, | ||
collect_traversed_dirs: bool | ||||
|
r43567 | ) | ||
), | ||||
)?; | ||||
|
r42737 | |||
|
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) | ||||
} | ||||