From 160aa3910a64147efe9bd5a401e6c062be16cb35 Mon Sep 17 00:00:00 2001
From: timofey <tim@ongoteam.yaconnect.com>
Date: Sun, 3 Sep 2023 19:05:23 +0000
Subject: [PATCH] `SingularRobust`

---
 src/rstd/singular.rs | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/rstd/singular.rs b/src/rstd/singular.rs
index cdb7e0c..262dd05 100644
--- a/src/rstd/singular.rs
+++ b/src/rstd/singular.rs
@@ -1,3 +1,4 @@
+use crate::func::context::*;
 use crate::rcore::*;
 
 use super::*;
@@ -39,6 +40,10 @@ pub struct SingularResolver<'a, Ctx: Context<'a>> {
     points: Vec<Arc<dyn SingularResolution<'a, Ctx>>>,
 }
 
+pub struct SingularRobust<'a, Ctx: Context<'a>> {
+    resolver: Arc<SingularResolver<'a, Ctx>>,
+}
+
 #[derive(Debug)]
 pub enum SingularityError {
     OutOfBounds {
@@ -108,6 +113,21 @@ impl<'a, Ctx: Context<'a>> Resolver<'a, Ctx> for SingularResolver<'a, Ctx> {
     }
 }
 
+trait SingularCtx<'a>: Context<'a> {
+    fn from_singular(error: SingularityError) -> Self::LookupError;
+}
+
+impl<'a, Ctx: SingularCtx<'a>> Resolver<'a, Ctx> for SingularRobust<'a, Ctx> {
+    fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
+        self.resolver
+            .clone()
+            .resolve_robust(address)
+            .map_err(Ctx::from_singular)
+            .map_err(Err)
+            .unwrap_or_else(Ctx::pure)
+    }
+}
+
 impl<'a, Ctx: Context<'a>> PointsVisitor<'a, Ctx> for Vec<Arc<dyn SingularResolution<'a, Ctx>>> {
     fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) {
         self.push(Arc::new(point.clone()) as _);