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