tamer: f: impl_mono_map: Support for non-tuple struct

DEV-13163
main
Mike Gerwitz 2023-08-02 10:19:30 -04:00
parent 0ad7414b9e
commit 729871fe15
2 changed files with 40 additions and 11 deletions

View File

@ -28,7 +28,7 @@
//! program.
use super::{prelude::*, Doc, Ident, ObjectIndexToTree, Tpl};
use crate::{f::Map, num::Dim, span::Span};
use crate::{num::Dim, span::Span};
use std::fmt::Display;
#[cfg(doc)]
@ -68,15 +68,8 @@ impl Expr {
}
}
impl Map<Span> for Expr {
fn map(self, f: impl FnOnce(Span) -> Span) -> Self {
match self {
Self { span, .. } => Self {
span: f(span),
..self
},
}
}
impl_mono_map! {
Span => Expr { span, .. },
}
impl From<&Expr> for Span {

View File

@ -251,7 +251,43 @@ macro_rules! impl_mono_map {
}
}
)+
}
};
($($t:ty => $tup:ident{ $field:ident, .. },)+) => {
$(
impl $crate::f::TryMap<$t> for $tup {
fn try_map<E>(
self,
f: impl FnOnce($t) -> Self::FnResult<E>,
) -> Self::Result<E> {
match self {
Self{ $field: x, .. } => match f(x) {
Ok(y) => Ok(Self{ $field: y, ..self }),
Err((y, e)) => Err((
Self { $field: y, ..self },
e,
)),
},
}
}
}
impl $crate::f::Map<$t> for $tup {
fn map(self, f: impl FnOnce($t) -> $t) -> Self::Target {
use std::convert::Infallible;
use $crate::f::TryMap;
// `unwrap()` requires `E: Debug`,
// so this avoids that bound.
match self.try_map::<Infallible>(|x| Ok(f(x))) {
Ok(y) => y,
// Verbosely emphasize unreachability
Err::<_, (_, Infallible)>(_) => unreachable!(),
}
}
}
)+
};
}
/// A nullary [`Fn`] delaying some computation.