##// END OF EJS Templates
rust-cpython: rename inner_shared() to inner()...
Yuya Nishihara -
r44702:281642cd default
parent child Browse files
Show More
@@ -1,146 +1,146 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 use std::convert::TryInto;
12 use std::convert::TryInto;
13
13
14 use cpython::{
14 use cpython::{
15 exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
15 exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
16 Python,
16 Python,
17 };
17 };
18
18
19 use crate::dirstate::extract_dirstate;
19 use crate::dirstate::extract_dirstate;
20 use crate::ref_sharing::{PyLeaked, PySharedRefCell};
20 use crate::ref_sharing::{PyLeaked, PySharedRefCell};
21 use hg::{
21 use hg::{
22 utils::hg_path::{HgPath, HgPathBuf},
22 utils::hg_path::{HgPath, HgPathBuf},
23 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
23 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
24 EntryState,
24 EntryState,
25 };
25 };
26
26
27 py_class!(pub class Dirs |py| {
27 py_class!(pub class Dirs |py| {
28 data inner: PySharedRefCell<DirsMultiset>;
28 data inner_: PySharedRefCell<DirsMultiset>;
29
29
30 // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
30 // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
31 // a `list`)
31 // a `list`)
32 def __new__(
32 def __new__(
33 _cls,
33 _cls,
34 map: PyObject,
34 map: PyObject,
35 skip: Option<PyObject> = None
35 skip: Option<PyObject> = None
36 ) -> PyResult<Self> {
36 ) -> PyResult<Self> {
37 let mut skip_state: Option<EntryState> = None;
37 let mut skip_state: Option<EntryState> = None;
38 if let Some(skip) = skip {
38 if let Some(skip) = skip {
39 skip_state = Some(
39 skip_state = Some(
40 skip.extract::<PyBytes>(py)?.data(py)[0]
40 skip.extract::<PyBytes>(py)?.data(py)[0]
41 .try_into()
41 .try_into()
42 .map_err(|e: DirstateParseError| {
42 .map_err(|e: DirstateParseError| {
43 PyErr::new::<exc::ValueError, _>(py, e.to_string())
43 PyErr::new::<exc::ValueError, _>(py, e.to_string())
44 })?,
44 })?,
45 );
45 );
46 }
46 }
47 let inner = if let Ok(map) = map.cast_as::<PyDict>(py) {
47 let inner = if let Ok(map) = map.cast_as::<PyDict>(py) {
48 let dirstate = extract_dirstate(py, &map)?;
48 let dirstate = extract_dirstate(py, &map)?;
49 DirsMultiset::from_dirstate(&dirstate, skip_state)
49 DirsMultiset::from_dirstate(&dirstate, skip_state)
50 .map_err(|e| {
50 .map_err(|e| {
51 PyErr::new::<exc::ValueError, _>(py, e.to_string())
51 PyErr::new::<exc::ValueError, _>(py, e.to_string())
52 })?
52 })?
53 } else {
53 } else {
54 let map: Result<Vec<HgPathBuf>, PyErr> = map
54 let map: Result<Vec<HgPathBuf>, PyErr> = map
55 .iter(py)?
55 .iter(py)?
56 .map(|o| {
56 .map(|o| {
57 Ok(HgPathBuf::from_bytes(
57 Ok(HgPathBuf::from_bytes(
58 o?.extract::<PyBytes>(py)?.data(py),
58 o?.extract::<PyBytes>(py)?.data(py),
59 ))
59 ))
60 })
60 })
61 .collect();
61 .collect();
62 DirsMultiset::from_manifest(&map?)
62 DirsMultiset::from_manifest(&map?)
63 .map_err(|e| {
63 .map_err(|e| {
64 PyErr::new::<exc::ValueError, _>(py, e.to_string())
64 PyErr::new::<exc::ValueError, _>(py, e.to_string())
65 })?
65 })?
66 };
66 };
67
67
68 Self::create_instance(
68 Self::create_instance(
69 py,
69 py,
70 PySharedRefCell::new(inner),
70 PySharedRefCell::new(inner),
71 )
71 )
72 }
72 }
73
73
74 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
74 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
75 self.inner_shared(py).borrow_mut().add_path(
75 self.inner(py).borrow_mut().add_path(
76 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
76 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
77 ).and(Ok(py.None())).or_else(|e| {
77 ).and(Ok(py.None())).or_else(|e| {
78 match e {
78 match e {
79 DirstateMapError::EmptyPath => {
79 DirstateMapError::EmptyPath => {
80 Ok(py.None())
80 Ok(py.None())
81 },
81 },
82 e => {
82 e => {
83 Err(PyErr::new::<exc::ValueError, _>(
83 Err(PyErr::new::<exc::ValueError, _>(
84 py,
84 py,
85 e.to_string(),
85 e.to_string(),
86 ))
86 ))
87 }
87 }
88 }
88 }
89 })
89 })
90 }
90 }
91
91
92 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
92 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
93 self.inner_shared(py).borrow_mut().delete_path(
93 self.inner(py).borrow_mut().delete_path(
94 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
94 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
95 )
95 )
96 .and(Ok(py.None()))
96 .and(Ok(py.None()))
97 .or_else(|e| {
97 .or_else(|e| {
98 match e {
98 match e {
99 DirstateMapError::EmptyPath => {
99 DirstateMapError::EmptyPath => {
100 Ok(py.None())
100 Ok(py.None())
101 },
101 },
102 e => {
102 e => {
103 Err(PyErr::new::<exc::ValueError, _>(
103 Err(PyErr::new::<exc::ValueError, _>(
104 py,
104 py,
105 e.to_string(),
105 e.to_string(),
106 ))
106 ))
107 }
107 }
108 }
108 }
109 })
109 })
110 }
110 }
111 def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
111 def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
112 let leaked_ref = self.inner_shared(py).leak_immutable();
112 let leaked_ref = self.inner(py).leak_immutable();
113 DirsMultisetKeysIterator::from_inner(
113 DirsMultisetKeysIterator::from_inner(
114 py,
114 py,
115 unsafe { leaked_ref.map(py, |o| o.iter()) },
115 unsafe { leaked_ref.map(py, |o| o.iter()) },
116 )
116 )
117 }
117 }
118
118
119 def __contains__(&self, item: PyObject) -> PyResult<bool> {
119 def __contains__(&self, item: PyObject) -> PyResult<bool> {
120 Ok(self.inner_shared(py).borrow().contains(HgPath::new(
120 Ok(self.inner(py).borrow().contains(HgPath::new(
121 item.extract::<PyBytes>(py)?.data(py).as_ref(),
121 item.extract::<PyBytes>(py)?.data(py).as_ref(),
122 )))
122 )))
123 }
123 }
124 });
124 });
125
125
126 py_shared_ref!(Dirs, DirsMultiset, inner, inner_shared);
126 py_shared_ref!(Dirs, DirsMultiset, inner_, inner);
127
127
128 impl Dirs {
128 impl Dirs {
129 pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
129 pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
130 Self::create_instance(py, PySharedRefCell::new(d))
130 Self::create_instance(py, PySharedRefCell::new(d))
131 }
131 }
132
132
133 fn translate_key(
133 fn translate_key(
134 py: Python,
134 py: Python,
135 res: &HgPathBuf,
135 res: &HgPathBuf,
136 ) -> PyResult<Option<PyBytes>> {
136 ) -> PyResult<Option<PyBytes>> {
137 Ok(Some(PyBytes::new(py, res.as_ref())))
137 Ok(Some(PyBytes::new(py, res.as_ref())))
138 }
138 }
139 }
139 }
140
140
141 py_shared_iterator!(
141 py_shared_iterator!(
142 DirsMultisetKeysIterator,
142 DirsMultisetKeysIterator,
143 PyLeaked<DirsMultisetIter<'static>>,
143 PyLeaked<DirsMultisetIter<'static>>,
144 Dirs::translate_key,
144 Dirs::translate_key,
145 Option<PyBytes>
145 Option<PyBytes>
146 );
146 );
@@ -1,522 +1,522 b''
1 // dirstate_map.rs
1 // dirstate_map.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::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::{Ref, 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
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
19
20 use crate::{
20 use crate::{
21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
22 dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
22 dirstate::{dirs_multiset::Dirs, make_dirstate_tuple},
23 ref_sharing::{PyLeaked, PySharedRefCell},
23 ref_sharing::{PyLeaked, PySharedRefCell},
24 };
24 };
25 use hg::{
25 use hg::{
26 utils::hg_path::{HgPath, HgPathBuf},
26 utils::hg_path::{HgPath, HgPathBuf},
27 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
27 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
28 DirstateMapError, DirstateParents, DirstateParseError, EntryState,
28 DirstateMapError, DirstateParents, DirstateParseError, EntryState,
29 StateMapIter, PARENT_SIZE,
29 StateMapIter, PARENT_SIZE,
30 };
30 };
31
31
32 // TODO
32 // TODO
33 // This object needs to share references to multiple members of its Rust
33 // This object needs to share references to multiple members of its Rust
34 // inner struct, namely `copy_map`, `dirs` and `all_dirs`.
34 // inner struct, namely `copy_map`, `dirs` and `all_dirs`.
35 // Right now `CopyMap` is done, but it needs to have an explicit reference
35 // Right now `CopyMap` is done, but it needs to have an explicit reference
36 // to `RustDirstateMap` which itself needs to have an encapsulation for
36 // to `RustDirstateMap` which itself needs to have an encapsulation for
37 // every method in `CopyMap` (copymapcopy, etc.).
37 // every method in `CopyMap` (copymapcopy, etc.).
38 // This is ugly and hard to maintain.
38 // This is ugly and hard to maintain.
39 // The same logic applies to `dirs` and `all_dirs`, however the `Dirs`
39 // The same logic applies to `dirs` and `all_dirs`, however the `Dirs`
40 // `py_class!` is already implemented and does not mention
40 // `py_class!` is already implemented and does not mention
41 // `RustDirstateMap`, rightfully so.
41 // `RustDirstateMap`, rightfully so.
42 // All attributes also have to have a separate refcount data attribute for
42 // All attributes also have to have a separate refcount data attribute for
43 // leaks, with all methods that go along for reference sharing.
43 // leaks, with all methods that go along for reference sharing.
44 py_class!(pub class DirstateMap |py| {
44 py_class!(pub class DirstateMap |py| {
45 data inner: PySharedRefCell<RustDirstateMap>;
45 data inner_: PySharedRefCell<RustDirstateMap>;
46
46
47 def __new__(_cls, _root: PyObject) -> PyResult<Self> {
47 def __new__(_cls, _root: PyObject) -> PyResult<Self> {
48 let inner = RustDirstateMap::default();
48 let inner = RustDirstateMap::default();
49 Self::create_instance(
49 Self::create_instance(
50 py,
50 py,
51 PySharedRefCell::new(inner),
51 PySharedRefCell::new(inner),
52 )
52 )
53 }
53 }
54
54
55 def clear(&self) -> PyResult<PyObject> {
55 def clear(&self) -> PyResult<PyObject> {
56 self.inner_shared(py).borrow_mut().clear();
56 self.inner(py).borrow_mut().clear();
57 Ok(py.None())
57 Ok(py.None())
58 }
58 }
59
59
60 def get(
60 def get(
61 &self,
61 &self,
62 key: PyObject,
62 key: PyObject,
63 default: Option<PyObject> = None
63 default: Option<PyObject> = None
64 ) -> PyResult<Option<PyObject>> {
64 ) -> PyResult<Option<PyObject>> {
65 let key = key.extract::<PyBytes>(py)?;
65 let key = key.extract::<PyBytes>(py)?;
66 match self.inner_shared(py).borrow().get(HgPath::new(key.data(py))) {
66 match self.inner(py).borrow().get(HgPath::new(key.data(py))) {
67 Some(entry) => {
67 Some(entry) => {
68 Ok(Some(make_dirstate_tuple(py, entry)?))
68 Ok(Some(make_dirstate_tuple(py, entry)?))
69 },
69 },
70 None => Ok(default)
70 None => Ok(default)
71 }
71 }
72 }
72 }
73
73
74 def addfile(
74 def addfile(
75 &self,
75 &self,
76 f: PyObject,
76 f: PyObject,
77 oldstate: PyObject,
77 oldstate: PyObject,
78 state: PyObject,
78 state: PyObject,
79 mode: PyObject,
79 mode: PyObject,
80 size: PyObject,
80 size: PyObject,
81 mtime: PyObject
81 mtime: PyObject
82 ) -> PyResult<PyObject> {
82 ) -> PyResult<PyObject> {
83 self.inner_shared(py).borrow_mut().add_file(
83 self.inner(py).borrow_mut().add_file(
84 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
84 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
85 oldstate.extract::<PyBytes>(py)?.data(py)[0]
85 oldstate.extract::<PyBytes>(py)?.data(py)[0]
86 .try_into()
86 .try_into()
87 .map_err(|e: DirstateParseError| {
87 .map_err(|e: DirstateParseError| {
88 PyErr::new::<exc::ValueError, _>(py, e.to_string())
88 PyErr::new::<exc::ValueError, _>(py, e.to_string())
89 })?,
89 })?,
90 DirstateEntry {
90 DirstateEntry {
91 state: state.extract::<PyBytes>(py)?.data(py)[0]
91 state: state.extract::<PyBytes>(py)?.data(py)[0]
92 .try_into()
92 .try_into()
93 .map_err(|e: DirstateParseError| {
93 .map_err(|e: DirstateParseError| {
94 PyErr::new::<exc::ValueError, _>(py, e.to_string())
94 PyErr::new::<exc::ValueError, _>(py, e.to_string())
95 })?,
95 })?,
96 mode: mode.extract(py)?,
96 mode: mode.extract(py)?,
97 size: size.extract(py)?,
97 size: size.extract(py)?,
98 mtime: mtime.extract(py)?,
98 mtime: mtime.extract(py)?,
99 },
99 },
100 ).and(Ok(py.None())).or_else(|e: DirstateMapError| {
100 ).and(Ok(py.None())).or_else(|e: DirstateMapError| {
101 Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
101 Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
102 })
102 })
103 }
103 }
104
104
105 def removefile(
105 def removefile(
106 &self,
106 &self,
107 f: PyObject,
107 f: PyObject,
108 oldstate: PyObject,
108 oldstate: PyObject,
109 size: PyObject
109 size: PyObject
110 ) -> PyResult<PyObject> {
110 ) -> PyResult<PyObject> {
111 self.inner_shared(py).borrow_mut()
111 self.inner(py).borrow_mut()
112 .remove_file(
112 .remove_file(
113 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
113 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
114 oldstate.extract::<PyBytes>(py)?.data(py)[0]
114 oldstate.extract::<PyBytes>(py)?.data(py)[0]
115 .try_into()
115 .try_into()
116 .map_err(|e: DirstateParseError| {
116 .map_err(|e: DirstateParseError| {
117 PyErr::new::<exc::ValueError, _>(py, e.to_string())
117 PyErr::new::<exc::ValueError, _>(py, e.to_string())
118 })?,
118 })?,
119 size.extract(py)?,
119 size.extract(py)?,
120 )
120 )
121 .or_else(|_| {
121 .or_else(|_| {
122 Err(PyErr::new::<exc::OSError, _>(
122 Err(PyErr::new::<exc::OSError, _>(
123 py,
123 py,
124 "Dirstate error".to_string(),
124 "Dirstate error".to_string(),
125 ))
125 ))
126 })?;
126 })?;
127 Ok(py.None())
127 Ok(py.None())
128 }
128 }
129
129
130 def dropfile(
130 def dropfile(
131 &self,
131 &self,
132 f: PyObject,
132 f: PyObject,
133 oldstate: PyObject
133 oldstate: PyObject
134 ) -> PyResult<PyBool> {
134 ) -> PyResult<PyBool> {
135 self.inner_shared(py).borrow_mut()
135 self.inner(py).borrow_mut()
136 .drop_file(
136 .drop_file(
137 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
137 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
138 oldstate.extract::<PyBytes>(py)?.data(py)[0]
138 oldstate.extract::<PyBytes>(py)?.data(py)[0]
139 .try_into()
139 .try_into()
140 .map_err(|e: DirstateParseError| {
140 .map_err(|e: DirstateParseError| {
141 PyErr::new::<exc::ValueError, _>(py, e.to_string())
141 PyErr::new::<exc::ValueError, _>(py, e.to_string())
142 })?,
142 })?,
143 )
143 )
144 .and_then(|b| Ok(b.to_py_object(py)))
144 .and_then(|b| Ok(b.to_py_object(py)))
145 .or_else(|_| {
145 .or_else(|_| {
146 Err(PyErr::new::<exc::OSError, _>(
146 Err(PyErr::new::<exc::OSError, _>(
147 py,
147 py,
148 "Dirstate error".to_string(),
148 "Dirstate error".to_string(),
149 ))
149 ))
150 })
150 })
151 }
151 }
152
152
153 def clearambiguoustimes(
153 def clearambiguoustimes(
154 &self,
154 &self,
155 files: PyObject,
155 files: PyObject,
156 now: PyObject
156 now: PyObject
157 ) -> PyResult<PyObject> {
157 ) -> PyResult<PyObject> {
158 let files: PyResult<Vec<HgPathBuf>> = files
158 let files: PyResult<Vec<HgPathBuf>> = files
159 .iter(py)?
159 .iter(py)?
160 .map(|filename| {
160 .map(|filename| {
161 Ok(HgPathBuf::from_bytes(
161 Ok(HgPathBuf::from_bytes(
162 filename?.extract::<PyBytes>(py)?.data(py),
162 filename?.extract::<PyBytes>(py)?.data(py),
163 ))
163 ))
164 })
164 })
165 .collect();
165 .collect();
166 self.inner_shared(py).borrow_mut()
166 self.inner(py).borrow_mut()
167 .clear_ambiguous_times(files?, now.extract(py)?);
167 .clear_ambiguous_times(files?, now.extract(py)?);
168 Ok(py.None())
168 Ok(py.None())
169 }
169 }
170
170
171 // TODO share the reference
171 // TODO share the reference
172 def nonnormalentries(&self) -> PyResult<PyObject> {
172 def nonnormalentries(&self) -> PyResult<PyObject> {
173 let (non_normal, other_parent) =
173 let (non_normal, other_parent) =
174 self.inner_shared(py).borrow().non_normal_other_parent_entries();
174 self.inner(py).borrow().non_normal_other_parent_entries();
175
175
176 let locals = PyDict::new(py);
176 let locals = PyDict::new(py);
177 locals.set_item(
177 locals.set_item(
178 py,
178 py,
179 "non_normal",
179 "non_normal",
180 non_normal
180 non_normal
181 .iter()
181 .iter()
182 .map(|v| PyBytes::new(py, v.as_ref()))
182 .map(|v| PyBytes::new(py, v.as_ref()))
183 .collect::<Vec<PyBytes>>()
183 .collect::<Vec<PyBytes>>()
184 .to_py_object(py),
184 .to_py_object(py),
185 )?;
185 )?;
186 locals.set_item(
186 locals.set_item(
187 py,
187 py,
188 "other_parent",
188 "other_parent",
189 other_parent
189 other_parent
190 .iter()
190 .iter()
191 .map(|v| PyBytes::new(py, v.as_ref()))
191 .map(|v| PyBytes::new(py, v.as_ref()))
192 .collect::<Vec<PyBytes>>()
192 .collect::<Vec<PyBytes>>()
193 .to_py_object(py),
193 .to_py_object(py),
194 )?;
194 )?;
195
195
196 py.eval("set(non_normal), set(other_parent)", None, Some(&locals))
196 py.eval("set(non_normal), set(other_parent)", None, Some(&locals))
197 }
197 }
198
198
199 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
199 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
200 let d = d.extract::<PyBytes>(py)?;
200 let d = d.extract::<PyBytes>(py)?;
201 Ok(self.inner_shared(py).borrow_mut()
201 Ok(self.inner(py).borrow_mut()
202 .has_tracked_dir(HgPath::new(d.data(py)))
202 .has_tracked_dir(HgPath::new(d.data(py)))
203 .map_err(|e| {
203 .map_err(|e| {
204 PyErr::new::<exc::ValueError, _>(py, e.to_string())
204 PyErr::new::<exc::ValueError, _>(py, e.to_string())
205 })?
205 })?
206 .to_py_object(py))
206 .to_py_object(py))
207 }
207 }
208
208
209 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
209 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
210 let d = d.extract::<PyBytes>(py)?;
210 let d = d.extract::<PyBytes>(py)?;
211 Ok(self.inner_shared(py).borrow_mut()
211 Ok(self.inner(py).borrow_mut()
212 .has_dir(HgPath::new(d.data(py)))
212 .has_dir(HgPath::new(d.data(py)))
213 .map_err(|e| {
213 .map_err(|e| {
214 PyErr::new::<exc::ValueError, _>(py, e.to_string())
214 PyErr::new::<exc::ValueError, _>(py, e.to_string())
215 })?
215 })?
216 .to_py_object(py))
216 .to_py_object(py))
217 }
217 }
218
218
219 def parents(&self, st: PyObject) -> PyResult<PyTuple> {
219 def parents(&self, st: PyObject) -> PyResult<PyTuple> {
220 self.inner_shared(py).borrow_mut()
220 self.inner(py).borrow_mut()
221 .parents(st.extract::<PyBytes>(py)?.data(py))
221 .parents(st.extract::<PyBytes>(py)?.data(py))
222 .and_then(|d| {
222 .and_then(|d| {
223 Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2))
223 Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2))
224 .to_py_object(py))
224 .to_py_object(py))
225 })
225 })
226 .or_else(|_| {
226 .or_else(|_| {
227 Err(PyErr::new::<exc::OSError, _>(
227 Err(PyErr::new::<exc::OSError, _>(
228 py,
228 py,
229 "Dirstate error".to_string(),
229 "Dirstate error".to_string(),
230 ))
230 ))
231 })
231 })
232 }
232 }
233
233
234 def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> {
234 def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> {
235 let p1 = extract_node_id(py, &p1)?;
235 let p1 = extract_node_id(py, &p1)?;
236 let p2 = extract_node_id(py, &p2)?;
236 let p2 = extract_node_id(py, &p2)?;
237
237
238 self.inner_shared(py).borrow_mut()
238 self.inner(py).borrow_mut()
239 .set_parents(&DirstateParents { p1, p2 });
239 .set_parents(&DirstateParents { p1, p2 });
240 Ok(py.None())
240 Ok(py.None())
241 }
241 }
242
242
243 def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
243 def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
244 match self.inner_shared(py).borrow_mut()
244 match self.inner(py).borrow_mut()
245 .read(st.extract::<PyBytes>(py)?.data(py))
245 .read(st.extract::<PyBytes>(py)?.data(py))
246 {
246 {
247 Ok(Some(parents)) => Ok(Some(
247 Ok(Some(parents)) => Ok(Some(
248 (PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2))
248 (PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2))
249 .to_py_object(py)
249 .to_py_object(py)
250 .into_object(),
250 .into_object(),
251 )),
251 )),
252 Ok(None) => Ok(Some(py.None())),
252 Ok(None) => Ok(Some(py.None())),
253 Err(_) => Err(PyErr::new::<exc::OSError, _>(
253 Err(_) => Err(PyErr::new::<exc::OSError, _>(
254 py,
254 py,
255 "Dirstate error".to_string(),
255 "Dirstate error".to_string(),
256 )),
256 )),
257 }
257 }
258 }
258 }
259 def write(
259 def write(
260 &self,
260 &self,
261 p1: PyObject,
261 p1: PyObject,
262 p2: PyObject,
262 p2: PyObject,
263 now: PyObject
263 now: PyObject
264 ) -> PyResult<PyBytes> {
264 ) -> PyResult<PyBytes> {
265 let now = Duration::new(now.extract(py)?, 0);
265 let now = Duration::new(now.extract(py)?, 0);
266 let parents = DirstateParents {
266 let parents = DirstateParents {
267 p1: extract_node_id(py, &p1)?,
267 p1: extract_node_id(py, &p1)?,
268 p2: extract_node_id(py, &p2)?,
268 p2: extract_node_id(py, &p2)?,
269 };
269 };
270
270
271 match self.inner_shared(py).borrow_mut().pack(parents, now) {
271 match self.inner(py).borrow_mut().pack(parents, now) {
272 Ok(packed) => Ok(PyBytes::new(py, &packed)),
272 Ok(packed) => Ok(PyBytes::new(py, &packed)),
273 Err(_) => Err(PyErr::new::<exc::OSError, _>(
273 Err(_) => Err(PyErr::new::<exc::OSError, _>(
274 py,
274 py,
275 "Dirstate error".to_string(),
275 "Dirstate error".to_string(),
276 )),
276 )),
277 }
277 }
278 }
278 }
279
279
280 def filefoldmapasdict(&self) -> PyResult<PyDict> {
280 def filefoldmapasdict(&self) -> PyResult<PyDict> {
281 let dict = PyDict::new(py);
281 let dict = PyDict::new(py);
282 for (key, value) in
282 for (key, value) in
283 self.inner_shared(py).borrow_mut().build_file_fold_map().iter()
283 self.inner(py).borrow_mut().build_file_fold_map().iter()
284 {
284 {
285 dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
285 dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
286 }
286 }
287 Ok(dict)
287 Ok(dict)
288 }
288 }
289
289
290 def __len__(&self) -> PyResult<usize> {
290 def __len__(&self) -> PyResult<usize> {
291 Ok(self.inner_shared(py).borrow().len())
291 Ok(self.inner(py).borrow().len())
292 }
292 }
293
293
294 def __contains__(&self, key: PyObject) -> PyResult<bool> {
294 def __contains__(&self, key: PyObject) -> PyResult<bool> {
295 let key = key.extract::<PyBytes>(py)?;
295 let key = key.extract::<PyBytes>(py)?;
296 Ok(self.inner_shared(py).borrow().contains_key(HgPath::new(key.data(py))))
296 Ok(self.inner(py).borrow().contains_key(HgPath::new(key.data(py))))
297 }
297 }
298
298
299 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
299 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
300 let key = key.extract::<PyBytes>(py)?;
300 let key = key.extract::<PyBytes>(py)?;
301 let key = HgPath::new(key.data(py));
301 let key = HgPath::new(key.data(py));
302 match self.inner_shared(py).borrow().get(key) {
302 match self.inner(py).borrow().get(key) {
303 Some(entry) => {
303 Some(entry) => {
304 Ok(make_dirstate_tuple(py, entry)?)
304 Ok(make_dirstate_tuple(py, entry)?)
305 },
305 },
306 None => Err(PyErr::new::<exc::KeyError, _>(
306 None => Err(PyErr::new::<exc::KeyError, _>(
307 py,
307 py,
308 String::from_utf8_lossy(key.as_bytes()),
308 String::from_utf8_lossy(key.as_bytes()),
309 )),
309 )),
310 }
310 }
311 }
311 }
312
312
313 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
313 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
314 let leaked_ref = self.inner_shared(py).leak_immutable();
314 let leaked_ref = self.inner(py).leak_immutable();
315 DirstateMapKeysIterator::from_inner(
315 DirstateMapKeysIterator::from_inner(
316 py,
316 py,
317 unsafe { leaked_ref.map(py, |o| o.iter()) },
317 unsafe { leaked_ref.map(py, |o| o.iter()) },
318 )
318 )
319 }
319 }
320
320
321 def items(&self) -> PyResult<DirstateMapItemsIterator> {
321 def items(&self) -> PyResult<DirstateMapItemsIterator> {
322 let leaked_ref = self.inner_shared(py).leak_immutable();
322 let leaked_ref = self.inner(py).leak_immutable();
323 DirstateMapItemsIterator::from_inner(
323 DirstateMapItemsIterator::from_inner(
324 py,
324 py,
325 unsafe { leaked_ref.map(py, |o| o.iter()) },
325 unsafe { leaked_ref.map(py, |o| o.iter()) },
326 )
326 )
327 }
327 }
328
328
329 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
329 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
330 let leaked_ref = self.inner_shared(py).leak_immutable();
330 let leaked_ref = self.inner(py).leak_immutable();
331 DirstateMapKeysIterator::from_inner(
331 DirstateMapKeysIterator::from_inner(
332 py,
332 py,
333 unsafe { leaked_ref.map(py, |o| o.iter()) },
333 unsafe { leaked_ref.map(py, |o| o.iter()) },
334 )
334 )
335 }
335 }
336
336
337 def getdirs(&self) -> PyResult<Dirs> {
337 def getdirs(&self) -> PyResult<Dirs> {
338 // TODO don't copy, share the reference
338 // TODO don't copy, share the reference
339 self.inner_shared(py).borrow_mut().set_dirs()
339 self.inner(py).borrow_mut().set_dirs()
340 .map_err(|e| {
340 .map_err(|e| {
341 PyErr::new::<exc::ValueError, _>(py, e.to_string())
341 PyErr::new::<exc::ValueError, _>(py, e.to_string())
342 })?;
342 })?;
343 Dirs::from_inner(
343 Dirs::from_inner(
344 py,
344 py,
345 DirsMultiset::from_dirstate(
345 DirsMultiset::from_dirstate(
346 &self.inner_shared(py).borrow(),
346 &self.inner(py).borrow(),
347 Some(EntryState::Removed),
347 Some(EntryState::Removed),
348 )
348 )
349 .map_err(|e| {
349 .map_err(|e| {
350 PyErr::new::<exc::ValueError, _>(py, e.to_string())
350 PyErr::new::<exc::ValueError, _>(py, e.to_string())
351 })?,
351 })?,
352 )
352 )
353 }
353 }
354 def getalldirs(&self) -> PyResult<Dirs> {
354 def getalldirs(&self) -> PyResult<Dirs> {
355 // TODO don't copy, share the reference
355 // TODO don't copy, share the reference
356 self.inner_shared(py).borrow_mut().set_all_dirs()
356 self.inner(py).borrow_mut().set_all_dirs()
357 .map_err(|e| {
357 .map_err(|e| {
358 PyErr::new::<exc::ValueError, _>(py, e.to_string())
358 PyErr::new::<exc::ValueError, _>(py, e.to_string())
359 })?;
359 })?;
360 Dirs::from_inner(
360 Dirs::from_inner(
361 py,
361 py,
362 DirsMultiset::from_dirstate(
362 DirsMultiset::from_dirstate(
363 &self.inner_shared(py).borrow(),
363 &self.inner(py).borrow(),
364 None,
364 None,
365 ).map_err(|e| {
365 ).map_err(|e| {
366 PyErr::new::<exc::ValueError, _>(py, e.to_string())
366 PyErr::new::<exc::ValueError, _>(py, e.to_string())
367 })?,
367 })?,
368 )
368 )
369 }
369 }
370
370
371 // TODO all copymap* methods, see docstring above
371 // TODO all copymap* methods, see docstring above
372 def copymapcopy(&self) -> PyResult<PyDict> {
372 def copymapcopy(&self) -> PyResult<PyDict> {
373 let dict = PyDict::new(py);
373 let dict = PyDict::new(py);
374 for (key, value) in self.inner_shared(py).borrow().copy_map.iter() {
374 for (key, value) in self.inner(py).borrow().copy_map.iter() {
375 dict.set_item(
375 dict.set_item(
376 py,
376 py,
377 PyBytes::new(py, key.as_ref()),
377 PyBytes::new(py, key.as_ref()),
378 PyBytes::new(py, value.as_ref()),
378 PyBytes::new(py, value.as_ref()),
379 )?;
379 )?;
380 }
380 }
381 Ok(dict)
381 Ok(dict)
382 }
382 }
383
383
384 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
384 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
385 let key = key.extract::<PyBytes>(py)?;
385 let key = key.extract::<PyBytes>(py)?;
386 match self.inner_shared(py).borrow().copy_map.get(HgPath::new(key.data(py))) {
386 match self.inner(py).borrow().copy_map.get(HgPath::new(key.data(py))) {
387 Some(copy) => Ok(PyBytes::new(py, copy.as_ref())),
387 Some(copy) => Ok(PyBytes::new(py, copy.as_ref())),
388 None => Err(PyErr::new::<exc::KeyError, _>(
388 None => Err(PyErr::new::<exc::KeyError, _>(
389 py,
389 py,
390 String::from_utf8_lossy(key.data(py)),
390 String::from_utf8_lossy(key.data(py)),
391 )),
391 )),
392 }
392 }
393 }
393 }
394 def copymap(&self) -> PyResult<CopyMap> {
394 def copymap(&self) -> PyResult<CopyMap> {
395 CopyMap::from_inner(py, self.clone_ref(py))
395 CopyMap::from_inner(py, self.clone_ref(py))
396 }
396 }
397
397
398 def copymaplen(&self) -> PyResult<usize> {
398 def copymaplen(&self) -> PyResult<usize> {
399 Ok(self.inner_shared(py).borrow().copy_map.len())
399 Ok(self.inner(py).borrow().copy_map.len())
400 }
400 }
401 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
401 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
402 let key = key.extract::<PyBytes>(py)?;
402 let key = key.extract::<PyBytes>(py)?;
403 Ok(self
403 Ok(self
404 .inner_shared(py)
404 .inner(py)
405 .borrow()
405 .borrow()
406 .copy_map
406 .copy_map
407 .contains_key(HgPath::new(key.data(py))))
407 .contains_key(HgPath::new(key.data(py))))
408 }
408 }
409 def copymapget(
409 def copymapget(
410 &self,
410 &self,
411 key: PyObject,
411 key: PyObject,
412 default: Option<PyObject>
412 default: Option<PyObject>
413 ) -> PyResult<Option<PyObject>> {
413 ) -> PyResult<Option<PyObject>> {
414 let key = key.extract::<PyBytes>(py)?;
414 let key = key.extract::<PyBytes>(py)?;
415 match self
415 match self
416 .inner_shared(py)
416 .inner(py)
417 .borrow()
417 .borrow()
418 .copy_map
418 .copy_map
419 .get(HgPath::new(key.data(py)))
419 .get(HgPath::new(key.data(py)))
420 {
420 {
421 Some(copy) => Ok(Some(
421 Some(copy) => Ok(Some(
422 PyBytes::new(py, copy.as_ref()).into_object(),
422 PyBytes::new(py, copy.as_ref()).into_object(),
423 )),
423 )),
424 None => Ok(default),
424 None => Ok(default),
425 }
425 }
426 }
426 }
427 def copymapsetitem(
427 def copymapsetitem(
428 &self,
428 &self,
429 key: PyObject,
429 key: PyObject,
430 value: PyObject
430 value: PyObject
431 ) -> PyResult<PyObject> {
431 ) -> PyResult<PyObject> {
432 let key = key.extract::<PyBytes>(py)?;
432 let key = key.extract::<PyBytes>(py)?;
433 let value = value.extract::<PyBytes>(py)?;
433 let value = value.extract::<PyBytes>(py)?;
434 self.inner_shared(py).borrow_mut().copy_map.insert(
434 self.inner(py).borrow_mut().copy_map.insert(
435 HgPathBuf::from_bytes(key.data(py)),
435 HgPathBuf::from_bytes(key.data(py)),
436 HgPathBuf::from_bytes(value.data(py)),
436 HgPathBuf::from_bytes(value.data(py)),
437 );
437 );
438 Ok(py.None())
438 Ok(py.None())
439 }
439 }
440 def copymappop(
440 def copymappop(
441 &self,
441 &self,
442 key: PyObject,
442 key: PyObject,
443 default: Option<PyObject>
443 default: Option<PyObject>
444 ) -> PyResult<Option<PyObject>> {
444 ) -> PyResult<Option<PyObject>> {
445 let key = key.extract::<PyBytes>(py)?;
445 let key = key.extract::<PyBytes>(py)?;
446 match self
446 match self
447 .inner_shared(py)
447 .inner(py)
448 .borrow_mut()
448 .borrow_mut()
449 .copy_map
449 .copy_map
450 .remove(HgPath::new(key.data(py)))
450 .remove(HgPath::new(key.data(py)))
451 {
451 {
452 Some(_) => Ok(None),
452 Some(_) => Ok(None),
453 None => Ok(default),
453 None => Ok(default),
454 }
454 }
455 }
455 }
456
456
457 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
457 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
458 let leaked_ref = self.inner_shared(py).leak_immutable();
458 let leaked_ref = self.inner(py).leak_immutable();
459 CopyMapKeysIterator::from_inner(
459 CopyMapKeysIterator::from_inner(
460 py,
460 py,
461 unsafe { leaked_ref.map(py, |o| o.copy_map.iter()) },
461 unsafe { leaked_ref.map(py, |o| o.copy_map.iter()) },
462 )
462 )
463 }
463 }
464
464
465 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
465 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
466 let leaked_ref = self.inner_shared(py).leak_immutable();
466 let leaked_ref = self.inner(py).leak_immutable();
467 CopyMapItemsIterator::from_inner(
467 CopyMapItemsIterator::from_inner(
468 py,
468 py,
469 unsafe { leaked_ref.map(py, |o| o.copy_map.iter()) },
469 unsafe { leaked_ref.map(py, |o| o.copy_map.iter()) },
470 )
470 )
471 }
471 }
472
472
473 });
473 });
474
474
475 impl DirstateMap {
475 impl DirstateMap {
476 pub fn get_inner<'a>(
476 pub fn get_inner<'a>(
477 &'a self,
477 &'a self,
478 py: Python<'a>,
478 py: Python<'a>,
479 ) -> Ref<'a, RustDirstateMap> {
479 ) -> Ref<'a, RustDirstateMap> {
480 self.inner_shared(py).borrow()
480 self.inner(py).borrow()
481 }
481 }
482 fn translate_key(
482 fn translate_key(
483 py: Python,
483 py: Python,
484 res: (&HgPathBuf, &DirstateEntry),
484 res: (&HgPathBuf, &DirstateEntry),
485 ) -> PyResult<Option<PyBytes>> {
485 ) -> PyResult<Option<PyBytes>> {
486 Ok(Some(PyBytes::new(py, res.0.as_ref())))
486 Ok(Some(PyBytes::new(py, res.0.as_ref())))
487 }
487 }
488 fn translate_key_value(
488 fn translate_key_value(
489 py: Python,
489 py: Python,
490 res: (&HgPathBuf, &DirstateEntry),
490 res: (&HgPathBuf, &DirstateEntry),
491 ) -> PyResult<Option<(PyBytes, PyObject)>> {
491 ) -> PyResult<Option<(PyBytes, PyObject)>> {
492 let (f, entry) = res;
492 let (f, entry) = res;
493 Ok(Some((
493 Ok(Some((
494 PyBytes::new(py, f.as_ref()),
494 PyBytes::new(py, f.as_ref()),
495 make_dirstate_tuple(py, entry)?,
495 make_dirstate_tuple(py, entry)?,
496 )))
496 )))
497 }
497 }
498 }
498 }
499
499
500 py_shared_ref!(DirstateMap, RustDirstateMap, inner, inner_shared);
500 py_shared_ref!(DirstateMap, RustDirstateMap, inner_, inner);
501
501
502 py_shared_iterator!(
502 py_shared_iterator!(
503 DirstateMapKeysIterator,
503 DirstateMapKeysIterator,
504 PyLeaked<StateMapIter<'static>>,
504 PyLeaked<StateMapIter<'static>>,
505 DirstateMap::translate_key,
505 DirstateMap::translate_key,
506 Option<PyBytes>
506 Option<PyBytes>
507 );
507 );
508
508
509 py_shared_iterator!(
509 py_shared_iterator!(
510 DirstateMapItemsIterator,
510 DirstateMapItemsIterator,
511 PyLeaked<StateMapIter<'static>>,
511 PyLeaked<StateMapIter<'static>>,
512 DirstateMap::translate_key_value,
512 DirstateMap::translate_key_value,
513 Option<(PyBytes, PyObject)>
513 Option<(PyBytes, PyObject)>
514 );
514 );
515
515
516 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<[u8; PARENT_SIZE]> {
516 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<[u8; PARENT_SIZE]> {
517 let bytes = obj.extract::<PyBytes>(py)?;
517 let bytes = obj.extract::<PyBytes>(py)?;
518 match bytes.data(py).try_into() {
518 match bytes.data(py).try_into() {
519 Ok(s) => Ok(s),
519 Ok(s) => Ok(s),
520 Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
520 Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
521 }
521 }
522 }
522 }
General Comments 0
You need to be logged in to leave comments. Login now