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