##// END OF EJS Templates
rust-cpython: turn inline comments into non-doc comments
Yuya Nishihara -
r43482:88a9930e default
parent child Browse files
Show More
@@ -1,132 +1,132
1 // dirstate.rs
1 // dirstate.rs
2 //
2 //
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 //! Bindings for the `hg::dirstate` module provided by the
8 //! Bindings for the `hg::dirstate` module provided by the
9 //! `hg-core` package.
9 //! `hg-core` package.
10 //!
10 //!
11 //! From Python, this will be seen as `mercurial.rustext.dirstate`
11 //! From Python, this will be seen as `mercurial.rustext.dirstate`
12 mod copymap;
12 mod copymap;
13 mod dirs_multiset;
13 mod dirs_multiset;
14 mod dirstate_map;
14 mod dirstate_map;
15 use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
15 use crate::dirstate::{dirs_multiset::Dirs, dirstate_map::DirstateMap};
16 use cpython::{
16 use cpython::{
17 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
17 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
18 Python,
18 Python,
19 };
19 };
20 use hg::{
20 use hg::{
21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
22 StateMap,
22 StateMap,
23 };
23 };
24 use libc::{c_char, c_int};
24 use libc::{c_char, c_int};
25 #[cfg(feature = "python27")]
25 #[cfg(feature = "python27")]
26 use python27_sys as python_sys;
26 use python27_sys as python_sys;
27 #[cfg(feature = "python3")]
27 #[cfg(feature = "python3")]
28 use python3_sys as python_sys;
28 use python3_sys as python_sys;
29 use python_sys::PyCapsule_Import;
29 use python_sys::PyCapsule_Import;
30 use std::convert::TryFrom;
30 use std::convert::TryFrom;
31 use std::ffi::CStr;
31 use std::ffi::CStr;
32 use std::mem::transmute;
32 use std::mem::transmute;
33
33
34 /// C code uses a custom `dirstate_tuple` type, checks in multiple instances
34 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
35 /// for this type, and raises a Python `Exception` if the check does not pass.
35 // for this type, and raises a Python `Exception` if the check does not pass.
36 /// Because this type differs only in name from the regular Python tuple, it
36 // Because this type differs only in name from the regular Python tuple, it
37 /// would be a good idea in the near future to remove it entirely to allow
37 // would be a good idea in the near future to remove it entirely to allow
38 /// for a pure Python tuple of the same effective structure to be used,
38 // for a pure Python tuple of the same effective structure to be used,
39 /// rendering this type and the capsule below useless.
39 // rendering this type and the capsule below useless.
40 type MakeDirstateTupleFn = unsafe extern "C" fn(
40 type MakeDirstateTupleFn = unsafe extern "C" fn(
41 state: c_char,
41 state: c_char,
42 mode: c_int,
42 mode: c_int,
43 size: c_int,
43 size: c_int,
44 mtime: c_int,
44 mtime: c_int,
45 ) -> *mut python_sys::PyObject;
45 ) -> *mut python_sys::PyObject;
46
46
47 /// This is largely a copy/paste from cindex.rs, pending the merge of a
47 // This is largely a copy/paste from cindex.rs, pending the merge of a
48 /// `py_capsule_fn!` macro in the rust-cpython project:
48 // `py_capsule_fn!` macro in the rust-cpython project:
49 /// https://github.com/dgrunwald/rust-cpython/pull/169
49 // https://github.com/dgrunwald/rust-cpython/pull/169
50 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult<MakeDirstateTupleFn> {
50 fn decapsule_make_dirstate_tuple(py: Python) -> PyResult<MakeDirstateTupleFn> {
51 unsafe {
51 unsafe {
52 let caps_name = CStr::from_bytes_with_nul_unchecked(
52 let caps_name = CStr::from_bytes_with_nul_unchecked(
53 b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
53 b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
54 );
54 );
55 let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
55 let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
56 if from_caps.is_null() {
56 if from_caps.is_null() {
57 return Err(PyErr::fetch(py));
57 return Err(PyErr::fetch(py));
58 }
58 }
59 Ok(transmute(from_caps))
59 Ok(transmute(from_caps))
60 }
60 }
61 }
61 }
62
62
63 pub fn make_dirstate_tuple(
63 pub fn make_dirstate_tuple(
64 py: Python,
64 py: Python,
65 entry: &DirstateEntry,
65 entry: &DirstateEntry,
66 ) -> PyResult<PyObject> {
66 ) -> PyResult<PyObject> {
67 let make = decapsule_make_dirstate_tuple(py)?;
67 let make = decapsule_make_dirstate_tuple(py)?;
68
68
69 let &DirstateEntry {
69 let &DirstateEntry {
70 state,
70 state,
71 mode,
71 mode,
72 size,
72 size,
73 mtime,
73 mtime,
74 } = entry;
74 } = entry;
75 // Explicitly go through u8 first, then cast to platform-specific `c_char`
75 // Explicitly go through u8 first, then cast to platform-specific `c_char`
76 // because Into<u8> has a specific implementation while `as c_char` would
76 // because Into<u8> has a specific implementation while `as c_char` would
77 // just do a naive enum cast.
77 // just do a naive enum cast.
78 let state_code: u8 = state.into();
78 let state_code: u8 = state.into();
79
79
80 let maybe_obj = unsafe {
80 let maybe_obj = unsafe {
81 let ptr = make(state_code as c_char, mode, size, mtime);
81 let ptr = make(state_code as c_char, mode, size, mtime);
82 PyObject::from_owned_ptr_opt(py, ptr)
82 PyObject::from_owned_ptr_opt(py, ptr)
83 };
83 };
84 maybe_obj.ok_or_else(|| PyErr::fetch(py))
84 maybe_obj.ok_or_else(|| PyErr::fetch(py))
85 }
85 }
86
86
87 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
87 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
88 dmap.items(py)
88 dmap.items(py)
89 .iter()
89 .iter()
90 .map(|(filename, stats)| {
90 .map(|(filename, stats)| {
91 let stats = stats.extract::<PySequence>(py)?;
91 let stats = stats.extract::<PySequence>(py)?;
92 let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
92 let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
93 let state = EntryState::try_from(state.data(py)[0]).map_err(
93 let state = EntryState::try_from(state.data(py)[0]).map_err(
94 |e: DirstateParseError| {
94 |e: DirstateParseError| {
95 PyErr::new::<exc::ValueError, _>(py, e.to_string())
95 PyErr::new::<exc::ValueError, _>(py, e.to_string())
96 },
96 },
97 )?;
97 )?;
98 let mode = stats.get_item(py, 1)?.extract(py)?;
98 let mode = stats.get_item(py, 1)?.extract(py)?;
99 let size = stats.get_item(py, 2)?.extract(py)?;
99 let size = stats.get_item(py, 2)?.extract(py)?;
100 let mtime = stats.get_item(py, 3)?.extract(py)?;
100 let mtime = stats.get_item(py, 3)?.extract(py)?;
101 let filename = filename.extract::<PyBytes>(py)?;
101 let filename = filename.extract::<PyBytes>(py)?;
102 let filename = filename.data(py);
102 let filename = filename.data(py);
103 Ok((
103 Ok((
104 HgPathBuf::from(filename.to_owned()),
104 HgPathBuf::from(filename.to_owned()),
105 DirstateEntry {
105 DirstateEntry {
106 state,
106 state,
107 mode,
107 mode,
108 size,
108 size,
109 mtime,
109 mtime,
110 },
110 },
111 ))
111 ))
112 })
112 })
113 .collect()
113 .collect()
114 }
114 }
115
115
116 /// Create the module, with `__package__` given from parent
116 /// Create the module, with `__package__` given from parent
117 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
117 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
118 let dotted_name = &format!("{}.dirstate", package);
118 let dotted_name = &format!("{}.dirstate", package);
119 let m = PyModule::new(py, dotted_name)?;
119 let m = PyModule::new(py, dotted_name)?;
120
120
121 m.add(py, "__package__", package)?;
121 m.add(py, "__package__", package)?;
122 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
122 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
123
123
124 m.add_class::<Dirs>(py)?;
124 m.add_class::<Dirs>(py)?;
125 m.add_class::<DirstateMap>(py)?;
125 m.add_class::<DirstateMap>(py)?;
126
126
127 let sys = PyModule::import(py, "sys")?;
127 let sys = PyModule::import(py, "sys")?;
128 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
128 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
129 sys_modules.set_item(py, dotted_name, &m)?;
129 sys_modules.set_item(py, dotted_name, &m)?;
130
130
131 Ok(m)
131 Ok(m)
132 }
132 }
General Comments 0
You need to be logged in to leave comments. Login now