##// END OF EJS Templates
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
Raphaël Gomès -
r43567:478d0b1b default
parent child Browse files
Show More
@@ -0,0 +1,82 b''
1 // status.rs
2 //
3 // Copyright 2019, Raphaël Gomès <rgomes@octobus.net>
4 //
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.
7
8 //! Bindings for the `hg::status` module provided by the
9 //! `hg-core` crate. From Python, this will be seen as `rustext.dirstate.status`.
10 //!
11
12 use crate::dirstate::DirstateMap;
13 use cpython::exc::ValueError;
14 use cpython::{
15 PyBytes, PyErr, PyList, PyObject, PyResult, Python, PythonObject,
16 ToPyObject,
17 };
18 use hg::utils::files::get_path_from_bytes;
19
20 use hg::utils::hg_path::HgPath;
21 use hg::{status, utils::hg_path::HgPathBuf};
22
23 /// This will be useless once trait impls for collection are added to `PyBytes`
24 /// upstream.
25 fn collect_pybytes_list<P: AsRef<HgPath>>(
26 py: Python,
27 collection: &[P],
28 ) -> PyList {
29 let list = PyList::new(py, &[]);
30
31 for (i, path) in collection.iter().enumerate() {
32 list.insert_item(
33 py,
34 i,
35 PyBytes::new(py, path.as_ref().as_bytes()).into_object(),
36 )
37 }
38
39 list
40 }
41
42 pub fn status_wrapper(
43 py: Python,
44 dmap: DirstateMap,
45 root_dir: PyObject,
46 files: PyList,
47 list_clean: bool,
48 last_normal_time: i64,
49 check_exec: bool,
50 ) -> PyResult<(PyList, PyList, PyList, PyList, PyList, PyList, PyList)> {
51 let bytes = root_dir.extract::<PyBytes>(py)?;
52 let root_dir = get_path_from_bytes(bytes.data(py));
53
54 let dmap: DirstateMap = dmap.to_py_object(py);
55 let dmap = dmap.get_inner(py);
56
57 let files: PyResult<Vec<HgPathBuf>> = files
58 .iter(py)
59 .map(|f| Ok(HgPathBuf::from_bytes(f.extract::<PyBytes>(py)?.data(py))))
60 .collect();
61 let files = files?;
62
63 let (lookup, status_res) = status(
64 &dmap,
65 &root_dir,
66 &files,
67 list_clean,
68 last_normal_time,
69 check_exec,
70 )
71 .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?;
72
73 let modified = collect_pybytes_list(py, status_res.modified.as_ref());
74 let added = collect_pybytes_list(py, status_res.added.as_ref());
75 let removed = collect_pybytes_list(py, status_res.removed.as_ref());
76 let deleted = collect_pybytes_list(py, status_res.deleted.as_ref());
77 let clean = collect_pybytes_list(py, status_res.clean.as_ref());
78 let lookup = collect_pybytes_list(py, lookup.as_ref());
79 let unknown = PyList::new(py, &[]);
80
81 Ok((lookup, modified, added, removed, deleted, unknown, clean))
82 }
@@ -12,10 +12,13 b''
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 mod status;
16 use crate::dirstate::{
17 dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
18 };
16 use cpython::{
19 use cpython::{
17 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
20 exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult,
18 Python,
21 PySequence, Python,
19 };
22 };
20 use hg::{
23 use hg::{
21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
24 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
@@ -105,6 +108,21 b' pub fn init_module(py: Python, package: '
105
108
106 m.add_class::<Dirs>(py)?;
109 m.add_class::<Dirs>(py)?;
107 m.add_class::<DirstateMap>(py)?;
110 m.add_class::<DirstateMap>(py)?;
111 m.add(
112 py,
113 "status",
114 py_fn!(
115 py,
116 status_wrapper(
117 dmap: DirstateMap,
118 root_dir: PyObject,
119 files: PyList,
120 list_clean: bool,
121 last_normal_time: i64,
122 check_exec: bool
123 )
124 ),
125 )?;
108
126
109 let sys = PyModule::import(py, "sys")?;
127 let sys = PyModule::import(py, "sys")?;
110 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
128 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
@@ -8,7 +8,7 b''
8 //! Bindings for the `hg::dirstate::dirstate_map` file provided by the
8 //! Bindings for the `hg::dirstate::dirstate_map` file provided by the
9 //! `hg-core` package.
9 //! `hg-core` package.
10
10
11 use std::cell::RefCell;
11 use std::cell::{Ref, RefCell};
12 use std::convert::TryInto;
12 use std::convert::TryInto;
13 use std::time::Duration;
13 use std::time::Duration;
14
14
@@ -465,6 +465,12 b' py_class!(pub class DirstateMap |py| {'
465 });
465 });
466
466
467 impl DirstateMap {
467 impl DirstateMap {
468 pub fn get_inner<'a>(
469 &'a self,
470 py: Python<'a>,
471 ) -> Ref<'a, RustDirstateMap> {
472 self.inner_shared(py).borrow()
473 }
468 fn translate_key(
474 fn translate_key(
469 py: Python,
475 py: Python,
470 res: (&HgPathBuf, &DirstateEntry),
476 res: (&HgPathBuf, &DirstateEntry),
General Comments 0
You need to be logged in to leave comments. Login now