diff --git a/tamer/src/asg/graph/object.rs b/tamer/src/asg/graph/object.rs index 32131fdb..79a99ab5 100644 --- a/tamer/src/asg/graph/object.rs +++ b/tamer/src/asg/graph/object.rs @@ -123,7 +123,7 @@ use super::{Asg, AsgError}; use crate::{ diagnose::{panic::DiagnosticPanic, Annotate, AnnotatedSpan}, diagnostic_panic, - f::Map, + f::{Map, TryMap}, parse::util::SPair, span::{Span, UNKNOWN_SPAN}, }; @@ -735,6 +735,26 @@ impl ObjectIndex { asg.try_map_obj(self, f) } + /// Resolve the identifier and map over an inner `T` of the resulting + /// [`Object`] narrowed to [`ObjectKind`] `O`, + /// replacing the object on the given [`Asg`]. + /// + /// This uses [`Self::try_map_obj`] to retrieve the object from + /// the [`Asg`]. + /// + /// If this operation is [`Infallible`], + /// see [`Self::map_obj_inner`]. + pub fn try_map_obj_inner( + self, + asg: &mut Asg, + f: impl FnOnce(T) -> >::FnResult, + ) -> Result + where + O: TryMap = Result>, + { + self.try_map_obj(asg, O::try_fmap(f)) + } + /// Resolve the identifier and infallibly map over the resulting /// [`Object`] narrowed to [`ObjectKind`] `O`, /// replacing the object on the given [`Asg`]. @@ -751,6 +771,22 @@ impl ObjectIndex { } } + /// Resolve the identifier and map over an inner `T` of the resulting + /// [`Object`] narrowed to [`ObjectKind`] `O`, + /// replacing the object on the given [`Asg`]. + /// + /// This uses [`Self::map_obj`] to retrieve the object from + /// the [`Asg`]. + /// + /// If this operation is _not_ [`Infallible`], + /// see [`Self::try_map_obj_inner`]. + pub fn map_obj_inner(self, asg: &mut Asg, f: impl FnOnce(T) -> T) -> Self + where + O: Map, + { + self.map_obj(asg, O::fmap(f)) + } + /// Lift [`Self`] into [`Option`] and [`filter`](Option::filter) based /// on whether the [`ObjectRelatable::rel_ty`] of [`Self`]'s `O` /// matches that of `OB`. diff --git a/tamer/src/asg/graph/object/tpl.rs b/tamer/src/asg/graph/object/tpl.rs index c8efedb8..a1870e84 100644 --- a/tamer/src/asg/graph/object/tpl.rs +++ b/tamer/src/asg/graph/object/tpl.rs @@ -22,11 +22,7 @@ use std::fmt::Display; use super::{prelude::*, Doc, Expr, Ident}; -use crate::{ - f::{Map, TryMap}, - parse::util::SPair, - span::Span, -}; +use crate::{f::Map, parse::util::SPair, span::Span}; /// Template with associated name. #[derive(Debug, PartialEq, Eq)] @@ -193,6 +189,17 @@ impl TplShape { } } +/// Attempt to adapt a template shape to that of another. +/// +/// This returns a partially applied [`TplShape::try_adapt_to`], +/// where the remaining argument is `self`. +fn try_adapt_to( + other: TplShape, + tpl_name: Option, +) -> impl FnOnce(TplShape) -> Result { + move |s| s.try_adapt_to(other, tpl_name) +} + impl Display for TplShape { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { // phrase as "template with ..." @@ -221,11 +228,10 @@ object_rel! { let tpl_name = from_oi.name(asg); let span = to_oi.resolve(asg).span(); - from_oi.try_map_obj(asg, |tpl| { - tpl.try_map(|shape: TplShape| { - shape.try_adapt_to(TplShape::Expr(span), tpl_name) - }) - })?; + from_oi.try_map_obj_inner( + asg, + try_adapt_to(TplShape::Expr(span), tpl_name), + )?; Ok(commit(asg)) } @@ -250,12 +256,10 @@ object_rel! { .shape() .overwrite_span_if_any(apply.span()); - // TODO: Refactor; very similar to Expr edge above. - from_oi.try_map_obj(asg, |tpl| { - tpl.try_map(|shape: TplShape| { - shape.try_adapt_to(apply_shape, tpl_name) - }) - })?; + from_oi.try_map_obj_inner( + asg, + try_adapt_to(apply_shape, tpl_name), + )?; Ok(commit(asg)) }