--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Wed May 19 13:15:00 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Wed May 19 13:15:00 2021 +0200
@@ -29,13 +29,13 @@
use hg::{
dirstate::parsers::Timestamp,
dirstate_tree::dispatch::DirstateMapMethods,
+ dirstate_tree::on_disk::DirstateV2ParseError,
errors::HgError,
revlog::Node,
utils::files::normalize_case,
utils::hg_path::{HgPath, HgPathBuf},
DirsMultiset, DirstateEntry, DirstateError,
- DirstateMap as RustDirstateMap, DirstateMapError, DirstateParents,
- EntryState, StateMapIter,
+ DirstateMap as RustDirstateMap, DirstateParents, EntryState, StateMapIter,
};
// TODO
@@ -90,7 +90,12 @@
default: Option<PyObject> = None
) -> PyResult<Option<PyObject>> {
let key = key.extract::<PyBytes>(py)?;
- match self.inner(py).borrow().get(HgPath::new(key.data(py))) {
+ match self
+ .inner(py)
+ .borrow()
+ .get(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))?
+ {
Some(entry) => {
Ok(Some(make_dirstate_tuple(py, &entry)?))
},
@@ -124,7 +129,7 @@
size: size.extract(py)?,
mtime: mtime.extract(py)?,
},
- ).and(Ok(py.None())).or_else(|e: DirstateMapError| {
+ ).and(Ok(py.None())).or_else(|e: DirstateError| {
Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
})
}
@@ -190,8 +195,10 @@
))
})
.collect();
- self.inner(py).borrow_mut()
- .clear_ambiguous_times(files?, now.extract(py)?);
+ self.inner(py)
+ .borrow_mut()
+ .clear_ambiguous_times(files?, now.extract(py)?)
+ .map_err(|e| v2_error(py, e))?;
Ok(py.None())
}
@@ -199,6 +206,7 @@
let mut inner_shared = self.inner(py).borrow_mut();
let set = PySet::empty(py)?;
for path in inner_shared.iter_other_parent_paths() {
+ let path = path.map_err(|e| v2_error(py, e))?;
set.add(py, PyBytes::new(py, path.as_bytes()))?;
}
Ok(set.into_object())
@@ -210,28 +218,20 @@
def non_normal_entries_contains(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
- Ok(self
- .inner(py)
+ self.inner(py)
.borrow_mut()
- .non_normal_entries_contains(HgPath::new(key.data(py))))
+ .non_normal_entries_contains(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))
}
def non_normal_entries_display(&self) -> PyResult<PyString> {
- Ok(
- PyString::new(
- py,
- &format!(
- "NonNormalEntries: {}",
- hg::utils::join_display(
- self
- .inner(py)
- .borrow_mut()
- .iter_non_normal_paths(),
- ", "
- )
- )
- )
- )
+ let mut inner = self.inner(py).borrow_mut();
+ let paths = inner
+ .iter_non_normal_paths()
+ .collect::<Result<Vec<_>, _>>()
+ .map_err(|e| v2_error(py, e))?;
+ let formatted = format!("NonNormalEntries: {}", hg::utils::join_display(paths, ", "));
+ Ok(PyString::new(py, &formatted))
}
def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> {
@@ -248,6 +248,7 @@
let ret = PyList::new(py, &[]);
for filename in inner.non_normal_or_other_parent_paths() {
+ let filename = filename.map_err(|e| v2_error(py, e))?;
let as_pystring = PyBytes::new(py, filename.as_bytes());
ret.append(py, as_pystring.into_object());
}
@@ -320,7 +321,8 @@
def filefoldmapasdict(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
- for (path, entry) in self.inner(py).borrow_mut().iter() {
+ for item in self.inner(py).borrow_mut().iter() {
+ let (path, entry) = item.map_err(|e| v2_error(py, e))?;
if entry.state != EntryState::Removed {
let key = normalize_case(path);
let value = path;
@@ -340,13 +342,21 @@
def __contains__(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
- Ok(self.inner(py).borrow().contains_key(HgPath::new(key.data(py))))
+ self.inner(py)
+ .borrow()
+ .contains_key(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))
}
def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
let key = key.extract::<PyBytes>(py)?;
let key = HgPath::new(key.data(py));
- match self.inner(py).borrow().get(key) {
+ match self
+ .inner(py)
+ .borrow()
+ .get(key)
+ .map_err(|e| v2_error(py, e))?
+ {
Some(entry) => {
Ok(make_dirstate_tuple(py, &entry)?)
},
@@ -418,7 +428,8 @@
// TODO all copymap* methods, see docstring above
def copymapcopy(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
- for (key, value) in self.inner(py).borrow().copy_map_iter() {
+ for item in self.inner(py).borrow().copy_map_iter() {
+ let (key, value) = item.map_err(|e| v2_error(py, e))?;
dict.set_item(
py,
PyBytes::new(py, key.as_bytes()),
@@ -430,7 +441,12 @@
def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
let key = key.extract::<PyBytes>(py)?;
- match self.inner(py).borrow().copy_map_get(HgPath::new(key.data(py))) {
+ match self
+ .inner(py)
+ .borrow()
+ .copy_map_get(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))?
+ {
Some(copy) => Ok(PyBytes::new(py, copy.as_bytes())),
None => Err(PyErr::new::<exc::KeyError, _>(
py,
@@ -447,10 +463,10 @@
}
def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
- Ok(self
- .inner(py)
+ self.inner(py)
.borrow()
- .copy_map_contains_key(HgPath::new(key.data(py))))
+ .copy_map_contains_key(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))
}
def copymapget(
&self,
@@ -462,6 +478,7 @@
.inner(py)
.borrow()
.copy_map_get(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))?
{
Some(copy) => Ok(Some(
PyBytes::new(py, copy.as_bytes()).into_object(),
@@ -476,10 +493,13 @@
) -> PyResult<PyObject> {
let key = key.extract::<PyBytes>(py)?;
let value = value.extract::<PyBytes>(py)?;
- self.inner(py).borrow_mut().copy_map_insert(
- HgPathBuf::from_bytes(key.data(py)),
- HgPathBuf::from_bytes(value.data(py)),
- );
+ self.inner(py)
+ .borrow_mut()
+ .copy_map_insert(
+ HgPathBuf::from_bytes(key.data(py)),
+ HgPathBuf::from_bytes(value.data(py)),
+ )
+ .map_err(|e| v2_error(py, e))?;
Ok(py.None())
}
def copymappop(
@@ -492,6 +512,7 @@
.inner(py)
.borrow_mut()
.copy_map_remove(HgPath::new(key.data(py)))
+ .map_err(|e| v2_error(py, e))?
{
Some(_) => Ok(None),
None => Ok(default),
@@ -525,15 +546,16 @@
}
fn translate_key(
py: Python,
- res: (&HgPath, DirstateEntry),
+ res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
) -> PyResult<Option<PyBytes>> {
- Ok(Some(PyBytes::new(py, res.0.as_bytes())))
+ let (f, _entry) = res.map_err(|e| v2_error(py, e))?;
+ Ok(Some(PyBytes::new(py, f.as_bytes())))
}
fn translate_key_value(
py: Python,
- res: (&HgPath, DirstateEntry),
+ res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
) -> PyResult<Option<(PyBytes, PyObject)>> {
- let (f, entry) = res;
+ let (f, entry) = res.map_err(|e| v2_error(py, e))?;
Ok(Some((
PyBytes::new(py, f.as_bytes()),
make_dirstate_tuple(py, &entry)?,
@@ -562,3 +584,7 @@
Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
}
}
+
+pub(super) fn v2_error(py: Python<'_>, _: DirstateV2ParseError) -> PyErr {
+ PyErr::new::<exc::ValueError, _>(py, "corrupted dirstate-v2")
+}