annotate rust/hg-cpython/src/dirstate.rs @ 42747:760a7851e9ba

rust-parsers: move parser bindings to their own file and Python module This tidies up the Rust side while simplifying the Python side. Differential Revision: https://phab.mercurial-scm.org/D6627
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 10 Jul 2019 10:16:28 +0200
parents b3518b0baa47
children 7cae6bc29ff9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
1 // dirstate.rs
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
2 //
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
4 //
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
7
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
8 //! Bindings for the `hg::dirstate` module provided by the
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
9 //! `hg-core` package.
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
10 //!
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
11 //! From Python, this will be seen as `mercurial.rustext.dirstate`
42746
b3518b0baa47 rust-dirstate: create dirstate submodule in hg-cpython
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
12 mod dirs_multiset;
b3518b0baa47 rust-dirstate: create dirstate submodule in hg-cpython
Raphaël Gomès <rgomes@octobus.net>
parents: 42609
diff changeset
13 use crate::dirstate::dirs_multiset::Dirs;
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
14 use cpython::{
42747
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
15 PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence, Python,
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
16 };
42747
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
17 use hg::{DirstateEntry, DirstateVec};
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42558
diff changeset
18 use libc::{c_char, c_int};
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42558
diff changeset
19 #[cfg(feature = "python27")]
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42558
diff changeset
20 use python27_sys::PyCapsule_Import;
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42558
diff changeset
21 #[cfg(feature = "python3")]
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 42558
diff changeset
22 use python3_sys::PyCapsule_Import;
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
23 use std::ffi::CStr;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
24 use std::mem::transmute;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
25
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
26 /// C code uses a custom `dirstate_tuple` type, checks in multiple instances
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
27 /// for this type, and raises a Python `Exception` if the check does not pass.
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
28 /// Because this type differs only in name from the regular Python tuple, it
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
29 /// would be a good idea in the near future to remove it entirely to allow
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
30 /// for a pure Python tuple of the same effective structure to be used,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
31 /// rendering this type and the capsule below useless.
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
32 type MakeDirstateTupleFn = extern "C" fn(
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
33 state: c_char,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
34 mode: c_int,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
35 size: c_int,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
36 mtime: c_int,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
37 ) -> PyObject;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
38
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
39 /// This is largely a copy/paste from cindex.rs, pending the merge of a
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
40 /// `py_capsule_fn!` macro in the rust-cpython project:
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
41 /// https://github.com/dgrunwald/rust-cpython/pull/169
42747
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
42 pub fn decapsule_make_dirstate_tuple(
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
43 py: Python,
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
44 ) -> PyResult<MakeDirstateTupleFn> {
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
45 unsafe {
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
46 let caps_name = CStr::from_bytes_with_nul_unchecked(
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
47 b"mercurial.cext.parsers.make_dirstate_tuple_CAPI\0",
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
48 );
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
49 let from_caps = PyCapsule_Import(caps_name.as_ptr(), 0);
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
50 if from_caps.is_null() {
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
51 return Err(PyErr::fetch(py));
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
52 }
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
53 Ok(transmute(from_caps))
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
54 }
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
55 }
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
56
42747
760a7851e9ba rust-parsers: move parser bindings to their own file and Python module
Raphaël Gomès <rgomes@octobus.net>
parents: 42746
diff changeset
57 pub fn extract_dirstate_vec(
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
58 py: Python,
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
59 dmap: &PyDict,
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
60 ) -> Result<DirstateVec, PyErr> {
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
61 dmap.items(py)
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
62 .iter()
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
63 .map(|(filename, stats)| {
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
64 let stats = stats.extract::<PySequence>(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
65 let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
66 let state = state.data(py)[0] as i8;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
67 let mode = stats.get_item(py, 1)?.extract(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
68 let size = stats.get_item(py, 2)?.extract(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
69 let mtime = stats.get_item(py, 3)?.extract(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
70 let filename = filename.extract::<PyBytes>(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
71 let filename = filename.data(py);
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
72 Ok((
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
73 filename.to_owned(),
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
74 DirstateEntry {
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
75 state,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
76 mode,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
77 size,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
78 mtime,
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
79 },
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
80 ))
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
81 })
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
82 .collect()
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
83 }
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
84
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
85 /// Create the module, with `__package__` given from parent
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
86 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
87 let dotted_name = &format!("{}.dirstate", package);
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
88 let m = PyModule::new(py, dotted_name)?;
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
89
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
90 m.add(py, "__package__", package)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
91 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
92
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
93 m.add_class::<Dirs>(py)?;
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Raphaël Gomès <rgomes@octobus.net>
parents: 42408
diff changeset
94
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
95 let sys = PyModule::import(py, "sys")?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
96 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
97 sys_modules.set_item(py, dotted_name, &m)?;
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
98
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
99 Ok(m)
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
100 }