Mercurial > hg
comparison rust/hg-cpython/src/dirstate/dirstate_map.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 | b3dda04e851b |
children | 478d0b1bf0c5 |
comparison
equal
deleted
inserted
replaced
43207:4aa9f3a1c1df | 43208:1ca3823aeefd |
---|---|
14 | 14 |
15 use cpython::{ | 15 use cpython::{ |
16 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject, | 16 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject, |
17 PyResult, PyTuple, Python, PythonObject, ToPyObject, | 17 PyResult, PyTuple, Python, PythonObject, ToPyObject, |
18 }; | 18 }; |
19 use libc::c_char; | |
20 | 19 |
21 use crate::{ | 20 use crate::{ |
22 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, | 21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
23 dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs}, | 22 dirstate::{dirs_multiset::Dirs, make_dirstate_tuple}, |
24 ref_sharing::{PyLeakedRef, PySharedRefCell}, | 23 ref_sharing::{PyLeakedRef, PySharedRefCell}, |
25 }; | 24 }; |
26 use hg::{ | 25 use hg::{ |
27 utils::hg_path::{HgPath, HgPathBuf}, | 26 utils::hg_path::{HgPath, HgPathBuf}, |
28 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, | 27 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, |
64 default: Option<PyObject> = None | 63 default: Option<PyObject> = None |
65 ) -> PyResult<Option<PyObject>> { | 64 ) -> PyResult<Option<PyObject>> { |
66 let key = key.extract::<PyBytes>(py)?; | 65 let key = key.extract::<PyBytes>(py)?; |
67 match self.inner(py).borrow().get(HgPath::new(key.data(py))) { | 66 match self.inner(py).borrow().get(HgPath::new(key.data(py))) { |
68 Some(entry) => { | 67 Some(entry) => { |
69 // Explicitly go through u8 first, then cast to | 68 Ok(Some(make_dirstate_tuple(py, entry)?)) |
70 // platform-specific `c_char`. | |
71 let state: u8 = entry.state.into(); | |
72 Ok(Some(decapsule_make_dirstate_tuple(py)?( | |
73 state as c_char, | |
74 entry.mode, | |
75 entry.size, | |
76 entry.mtime, | |
77 ))) | |
78 }, | 69 }, |
79 None => Ok(default) | 70 None => Ok(default) |
80 } | 71 } |
81 } | 72 } |
82 | 73 |
301 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> { | 292 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> { |
302 let key = key.extract::<PyBytes>(py)?; | 293 let key = key.extract::<PyBytes>(py)?; |
303 let key = HgPath::new(key.data(py)); | 294 let key = HgPath::new(key.data(py)); |
304 match self.inner(py).borrow().get(key) { | 295 match self.inner(py).borrow().get(key) { |
305 Some(entry) => { | 296 Some(entry) => { |
306 // Explicitly go through u8 first, then cast to | 297 Ok(make_dirstate_tuple(py, entry)?) |
307 // platform-specific `c_char`. | |
308 let state: u8 = entry.state.into(); | |
309 Ok(decapsule_make_dirstate_tuple(py)?( | |
310 state as c_char, | |
311 entry.mode, | |
312 entry.size, | |
313 entry.mtime, | |
314 )) | |
315 }, | 298 }, |
316 None => Err(PyErr::new::<exc::KeyError, _>( | 299 None => Err(PyErr::new::<exc::KeyError, _>( |
317 py, | 300 py, |
318 String::from_utf8_lossy(key.as_bytes()), | 301 String::from_utf8_lossy(key.as_bytes()), |
319 )), | 302 )), |
491 fn translate_key_value( | 474 fn translate_key_value( |
492 py: Python, | 475 py: Python, |
493 res: (&HgPathBuf, &DirstateEntry), | 476 res: (&HgPathBuf, &DirstateEntry), |
494 ) -> PyResult<Option<(PyBytes, PyObject)>> { | 477 ) -> PyResult<Option<(PyBytes, PyObject)>> { |
495 let (f, entry) = res; | 478 let (f, entry) = res; |
496 | |
497 // Explicitly go through u8 first, then cast to | |
498 // platform-specific `c_char`. | |
499 let state: u8 = entry.state.into(); | |
500 Ok(Some(( | 479 Ok(Some(( |
501 PyBytes::new(py, f.as_ref()), | 480 PyBytes::new(py, f.as_ref()), |
502 decapsule_make_dirstate_tuple(py)?( | 481 make_dirstate_tuple(py, entry)?, |
503 state as c_char, | |
504 entry.mode, | |
505 entry.size, | |
506 entry.mtime, | |
507 ), | |
508 ))) | 482 ))) |
509 } | 483 } |
510 } | 484 } |
511 | 485 |
512 py_shared_ref!(DirstateMap, RustDirstateMap, inner, inner_shared); | 486 py_shared_ref!(DirstateMap, RustDirstateMap, inner, inner_shared); |