changeset 42800:79561843729a

rust-dirstate: handle invalid length of p1/p2 parameters It uses match syntax since map_err() failed to deduce the argument type.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 17 Aug 2019 18:06:08 +0900
parents 5399532510ae
children 1a535313ad1b
files rust/hg-cpython/src/dirstate/dirstate_map.rs
diffstat 1 files changed, 14 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs	Sat Aug 17 11:37:42 2019 +0900
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs	Sat Aug 17 18:06:08 2019 +0900
@@ -24,9 +24,8 @@
     ref_sharing::PySharedState,
 };
 use hg::{
-    DirsIterable, DirsMultiset, DirstateEntry,
-    DirstateMap as RustDirstateMap, DirstateParents, DirstateParseError,
-    EntryState,
+    DirsIterable, DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
+    DirstateParents, DirstateParseError, EntryState, PARENT_SIZE,
 };
 
 // TODO
@@ -239,9 +238,8 @@
     }
 
     def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> {
-        // TODO: don't panic; raise Python exception instead.
-        let p1 = p1.extract::<PyBytes>(py)?.data(py).try_into().unwrap();
-        let p2 = p2.extract::<PyBytes>(py)?.data(py).try_into().unwrap();
+        let p1 = extract_node_id(py, &p1)?;
+        let p2 = extract_node_id(py, &p2)?;
 
         self.inner(py)
             .borrow_mut()
@@ -275,9 +273,8 @@
     ) -> PyResult<PyBytes> {
         let now = Duration::new(now.extract(py)?, 0);
         let parents = DirstateParents {
-            // TODO: don't panic; raise Python exception instead.
-            p1: p1.extract::<PyBytes>(py)?.data(py).try_into().unwrap(),
-            p2: p2.extract::<PyBytes>(py)?.data(py).try_into().unwrap(),
+            p1: extract_node_id(py, &p1)?,
+            p2: extract_node_id(py, &p2)?,
         };
 
         match self.borrow_mut(py)?.pack(parents, now) {
@@ -508,3 +505,11 @@
     DirstateMap::translate_key_value,
     Option<(PyBytes, PyObject)>
 );
+
+fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<[u8; PARENT_SIZE]> {
+    let bytes = obj.extract::<PyBytes>(py)?;
+    match bytes.data(py).try_into() {
+        Ok(s) => Ok(s),
+        Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
+    }
+}