Mercurial > hg
diff rust/hg-cpython/src/dirstate.rs @ 43208:1ca3823aeefd
rust-cpython: add wrapper around decapsule_make_dirstate_tuple()
There are a couple of safety issues. First, the returned function pointer
must be unsafe. Second, its return value must be a raw pointer (i.e.
python27_sys::PyObject), not a cpython::PyObject. The wrapper function will
address these issues.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 13 Oct 2019 16:55:17 +0900 |
parents | 7a01778bc7b7 |
children | 8b355cbef16d |
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate.rs Sun Oct 13 02:10:26 2019 +0200 +++ b/rust/hg-cpython/src/dirstate.rs Sun Oct 13 16:55:17 2019 +0900 @@ -46,9 +46,7 @@ /// 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 -pub fn decapsule_make_dirstate_tuple( - py: Python, -) -> PyResult<MakeDirstateTupleFn> { +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", @@ -61,6 +59,25 @@ } } +pub fn make_dirstate_tuple( + py: Python, + entry: &DirstateEntry, +) -> PyResult<PyObject> { + let make = decapsule_make_dirstate_tuple(py)?; + + 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(); + Ok(make(state_code as c_char, mode, size, mtime)) +} + pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> { dmap.items(py) .iter()