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)?; |