Show More
@@ -1,118 +1,109 b'' | |||||
1 | // dirs_multiset.rs |
|
1 | // dirs_multiset.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::dirs_multiset` file provided by the |
|
8 | //! Bindings for the `hg::dirstate::dirs_multiset` file provided by the | |
9 | //! `hg-core` package. |
|
9 | //! `hg-core` package. | |
10 |
|
10 | |||
11 | use std::cell::RefCell; |
|
11 | use std::cell::RefCell; | |
12 |
|
12 | |||
13 | use cpython::{ |
|
13 | use cpython::{ | |
14 | exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, |
|
14 | exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, | |
15 | Python, UnsafePyLeaked, |
|
15 | Python, UnsafePyLeaked, | |
16 | }; |
|
16 | }; | |
17 |
|
17 | |||
18 | use hg::{ |
|
18 | use hg::{ | |
19 | utils::hg_path::{HgPath, HgPathBuf}, |
|
19 | utils::hg_path::{HgPath, HgPathBuf}, | |
20 | DirsMultiset, DirsMultisetIter, |
|
20 | DirsMultiset, DirsMultisetIter, | |
21 | }; |
|
21 | }; | |
22 |
|
22 | |||
23 | py_class!(pub class Dirs |py| { |
|
23 | py_class!(pub class Dirs |py| { | |
24 | @shared data inner: DirsMultiset; |
|
24 | @shared data inner: DirsMultiset; | |
25 |
|
25 | |||
26 | // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes |
|
26 | // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes | |
27 | // a `list`) |
|
27 | // a `list`) | |
28 | def __new__( |
|
28 | def __new__( | |
29 | _cls, |
|
29 | _cls, | |
30 | map: PyObject, |
|
30 | map: PyObject, | |
31 | ) -> PyResult<Self> { |
|
31 | ) -> PyResult<Self> { | |
32 | let inner = if map.cast_as::<PyDict>(py).is_ok() { |
|
32 | let inner = if map.cast_as::<PyDict>(py).is_ok() { | |
33 | let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \ |
|
33 | let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \ | |
34 | and should not be used when Rust is enabled"; |
|
34 | and should not be used when Rust is enabled"; | |
35 | return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string())) |
|
35 | return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string())) | |
36 | } else { |
|
36 | } else { | |
37 | let map: Result<Vec<HgPathBuf>, PyErr> = map |
|
37 | let map: Result<Vec<HgPathBuf>, PyErr> = map | |
38 | .iter(py)? |
|
38 | .iter(py)? | |
39 | .map(|o| { |
|
39 | .map(|o| { | |
40 | Ok(HgPathBuf::from_bytes( |
|
40 | Ok(HgPathBuf::from_bytes( | |
41 | o?.extract::<PyBytes>(py)?.data(py), |
|
41 | o?.extract::<PyBytes>(py)?.data(py), | |
42 | )) |
|
42 | )) | |
43 | }) |
|
43 | }) | |
44 | .collect(); |
|
44 | .collect(); | |
45 | DirsMultiset::from_manifest(&map?) |
|
45 | DirsMultiset::from_manifest(&map?) | |
46 | .map_err(|e| { |
|
46 | .map_err(|e| { | |
47 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
47 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
48 | })? |
|
48 | })? | |
49 | }; |
|
49 | }; | |
50 |
|
50 | |||
51 | Self::create_instance(py, inner) |
|
51 | Self::create_instance(py, inner) | |
52 | } |
|
52 | } | |
53 |
|
53 | |||
54 | def addpath(&self, path: PyObject) -> PyResult<PyObject> { |
|
54 | def addpath(&self, path: PyObject) -> PyResult<PyObject> { | |
55 | self.inner(py).borrow_mut().add_path( |
|
55 | self.inner(py).borrow_mut().add_path( | |
56 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), |
|
56 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), | |
57 |
).and(Ok(py.None())). |
|
57 | ).and(Ok(py.None())).map_err(|e| PyErr::new::<exc::ValueError, _>( | |
58 | match e { |
|
|||
59 | e => { |
|
|||
60 | Err(PyErr::new::<exc::ValueError, _>( |
|
|||
61 | py, |
|
58 | py, | |
62 | e.to_string(), |
|
59 | e.to_string(), | |
63 |
) |
|
60 | ) | |
64 |
|
|
61 | ) | |
65 | } |
|
|||
66 | }) |
|
|||
67 | } |
|
62 | } | |
68 |
|
63 | |||
69 | def delpath(&self, path: PyObject) -> PyResult<PyObject> { |
|
64 | def delpath(&self, path: PyObject) -> PyResult<PyObject> { | |
70 | self.inner(py).borrow_mut().delete_path( |
|
65 | self.inner(py).borrow_mut().delete_path( | |
71 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), |
|
66 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), | |
72 | ) |
|
67 | ) | |
73 | .and(Ok(py.None())) |
|
68 | .and(Ok(py.None())) | |
74 |
. |
|
69 | .map_err(|e| | |
75 | match e { |
|
70 | PyErr::new::<exc::ValueError, _>( | |
76 | e => { |
|
|||
77 | Err(PyErr::new::<exc::ValueError, _>( |
|
|||
78 | py, |
|
71 | py, | |
79 | e.to_string(), |
|
72 | e.to_string(), | |
80 |
) |
|
73 | ) | |
81 |
|
|
74 | ) | |
82 | } |
|
|||
83 | }) |
|
|||
84 | } |
|
75 | } | |
85 | def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> { |
|
76 | def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> { | |
86 | let leaked_ref = self.inner(py).leak_immutable(); |
|
77 | let leaked_ref = self.inner(py).leak_immutable(); | |
87 | DirsMultisetKeysIterator::from_inner( |
|
78 | DirsMultisetKeysIterator::from_inner( | |
88 | py, |
|
79 | py, | |
89 | unsafe { leaked_ref.map(py, |o| o.iter()) }, |
|
80 | unsafe { leaked_ref.map(py, |o| o.iter()) }, | |
90 | ) |
|
81 | ) | |
91 | } |
|
82 | } | |
92 |
|
83 | |||
93 | def __contains__(&self, item: PyObject) -> PyResult<bool> { |
|
84 | def __contains__(&self, item: PyObject) -> PyResult<bool> { | |
94 | Ok(self.inner(py).borrow().contains(HgPath::new( |
|
85 | Ok(self.inner(py).borrow().contains(HgPath::new( | |
95 | item.extract::<PyBytes>(py)?.data(py), |
|
86 | item.extract::<PyBytes>(py)?.data(py), | |
96 | ))) |
|
87 | ))) | |
97 | } |
|
88 | } | |
98 | }); |
|
89 | }); | |
99 |
|
90 | |||
100 | impl Dirs { |
|
91 | impl Dirs { | |
101 | pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> { |
|
92 | pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> { | |
102 | Self::create_instance(py, d) |
|
93 | Self::create_instance(py, d) | |
103 | } |
|
94 | } | |
104 |
|
95 | |||
105 | fn translate_key( |
|
96 | fn translate_key( | |
106 | py: Python, |
|
97 | py: Python, | |
107 | res: &HgPathBuf, |
|
98 | res: &HgPathBuf, | |
108 | ) -> PyResult<Option<PyBytes>> { |
|
99 | ) -> PyResult<Option<PyBytes>> { | |
109 | Ok(Some(PyBytes::new(py, res.as_bytes()))) |
|
100 | Ok(Some(PyBytes::new(py, res.as_bytes()))) | |
110 | } |
|
101 | } | |
111 | } |
|
102 | } | |
112 |
|
103 | |||
113 | py_shared_iterator!( |
|
104 | py_shared_iterator!( | |
114 | DirsMultisetKeysIterator, |
|
105 | DirsMultisetKeysIterator, | |
115 | UnsafePyLeaked<DirsMultisetIter<'static>>, |
|
106 | UnsafePyLeaked<DirsMultisetIter<'static>>, | |
116 | Dirs::translate_key, |
|
107 | Dirs::translate_key, | |
117 | Option<PyBytes> |
|
108 | Option<PyBytes> | |
118 | ); |
|
109 | ); |
General Comments 0
You need to be logged in to leave comments.
Login now