rust/hg-cpython/src/dirstate.rs
changeset 48044 d5528ac9b4f2
parent 48043 3e69bef2031a
child 48061 060cd909439f
equal deleted inserted replaced
48043:3e69bef2031a 48044:d5528ac9b4f2
    20     dirstate::{
    20     dirstate::{
    21         dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
    21         dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
    22     },
    22     },
    23     exceptions,
    23     exceptions,
    24 };
    24 };
    25 use cpython::{
    25 use cpython::{PyBytes, PyDict, PyList, PyModule, PyObject, PyResult, Python};
    26     PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, Python,
       
    27 };
       
    28 use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER;
    26 use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER;
    29 use hg::DirstateEntry;
       
    30 use libc::{c_char, c_int};
       
    31 
       
    32 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
       
    33 // for this type, and raises a Python `Exception` if the check does not pass.
       
    34 // Because this type differs only in name from the regular Python tuple, it
       
    35 // would be a good idea in the near future to remove it entirely to allow
       
    36 // for a pure Python tuple of the same effective structure to be used,
       
    37 // rendering this type and the capsule below useless.
       
    38 py_capsule_fn!(
       
    39     from mercurial.cext.parsers import make_dirstate_item_CAPI
       
    40         as make_dirstate_item_capi
       
    41         signature (
       
    42             state: c_char,
       
    43             mode: c_int,
       
    44             size: c_int,
       
    45             mtime: c_int,
       
    46         ) -> *mut RawPyObject
       
    47 );
       
    48 
       
    49 pub fn make_dirstate_item(
       
    50     py: Python,
       
    51     entry: &DirstateEntry,
       
    52 ) -> PyResult<PyObject> {
       
    53     // Explicitly go through u8 first, then cast to platform-specific `c_char`
       
    54     // because Into<u8> has a specific implementation while `as c_char` would
       
    55     // just do a naive enum cast.
       
    56     let state_code: u8 = entry.state().into();
       
    57 
       
    58     let make = make_dirstate_item_capi::retrieve(py)?;
       
    59     let maybe_obj = unsafe {
       
    60         let ptr = make(
       
    61             state_code as c_char,
       
    62             entry.mode(),
       
    63             entry.size(),
       
    64             entry.mtime(),
       
    65         );
       
    66         PyObject::from_owned_ptr_opt(py, ptr)
       
    67     };
       
    68     maybe_obj.ok_or_else(|| PyErr::fetch(py))
       
    69 }
       
    70 
    27 
    71 /// Create the module, with `__package__` given from parent
    28 /// Create the module, with `__package__` given from parent
    72 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
    29 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
    73     let dotted_name = &format!("{}.dirstate", package);
    30     let dotted_name = &format!("{}.dirstate", package);
    74     let m = PyModule::new(py, dotted_name)?;
    31     let m = PyModule::new(py, dotted_name)?;