rust-nodemap: add utils for propagating errors
authorGeorges Racinet <georges.racinet@octobus.net>
Tue, 11 Feb 2020 16:30:28 +0100
changeset 44516 26dd35ac59b8
parent 44515 d738b7a18438
child 44517 857cc79247ac
rust-nodemap: add utils for propagating errors This also updates the copyright notice Differential Revision: https://phab.mercurial-scm.org/D8156
rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs	Tue Feb 11 16:25:45 2020 +0100
+++ b/rust/hg-cpython/src/revlog.rs	Tue Feb 11 16:30:28 2020 +0100
@@ -1,16 +1,16 @@
 // revlog.rs
 //
-// Copyright 2019 Georges Racinet <georges.racinet@octobus.net>
+// Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net>
 //
 // This software may be used and distributed according to the terms of the
 // GNU General Public License version 2 or any later version.
 
 use crate::cindex;
 use cpython::{
-    ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
-    Python, PythonObject, ToPyObject,
+    exc::ValueError, ObjectProtocol, PyClone, PyDict, PyErr, PyModule,
+    PyObject, PyResult, PyTuple, Python, PythonObject, ToPyObject,
 };
-use hg::Revision;
+use hg::{nodemap::NodeMapError, NodeError, Revision};
 use std::cell::RefCell;
 
 /// Return a Struct implementing the Graph trait
@@ -224,6 +224,43 @@
     }
 }
 
+fn revlog_error(py: Python) -> PyErr {
+    match py
+        .import("mercurial.error")
+        .and_then(|m| m.get(py, "RevlogError"))
+    {
+        Err(e) => e,
+        Ok(cls) => PyErr::from_instance(py, cls),
+    }
+}
+
+fn rev_not_in_index(py: Python, rev: Revision) -> PyErr {
+    PyErr::new::<ValueError, _>(
+        py,
+        format!(
+            "Inconsistency: Revision {} found in nodemap \
+             is not in revlog index",
+            rev
+        ),
+    )
+}
+
+/// Standard treatment of NodeMapError
+fn nodemap_error(py: Python, err: NodeMapError) -> PyErr {
+    match err {
+        NodeMapError::MultipleResults => revlog_error(py),
+        NodeMapError::RevisionNotInIndex(r) => rev_not_in_index(py, r),
+        NodeMapError::InvalidNodePrefix(s) => invalid_node_prefix(py, &s),
+    }
+}
+
+fn invalid_node_prefix(py: Python, ne: &NodeError) -> PyErr {
+    PyErr::new::<ValueError, _>(
+        py,
+        format!("Invalid node or prefix: {:?}", ne),
+    )
+}
+
 /// Create the module, with __package__ given from parent
 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
     let dotted_name = &format!("{}.revlog", package);