#![allow(clippy::non_canonical_clone_impl)]
use std::fmt::{Debug, Display, Formatter};
use std::marker::PhantomData;
use derivative::Derivative;
use crate::traits::*;
impl<L: Optics<T>, T: ?Sized> Optics<T> for &L { type View = L::View; }
impl<L: OpticsFallible> OpticsFallible for &L {
type Success = L::Success;
type Error = L::Error;
fn success_witness(&self) -> L::Success { L::success_witness(self) }
}
impl<L: Getter<T>, T> Getter<T> for &L where Self::View: Sized {
fn view(&self, s: T) -> L::View { L::view(self, s) }
}
impl<'a, L: GetterRef<'a, T>, T: ?Sized + 'a> GetterRef<'a, T> for &L where L::View: 'a {
fn view_ref(&self, s: &'a T) -> &'a L::View { L::view_ref(self, s) }
}
impl<'a, L: GetterMut<'a, T>, T: ?Sized + 'a> GetterMut<'a, T> for &L where L::View: 'a {
fn view_mut(&self, s: &'a mut T) -> &'a mut L::View { L::view_mut(self, s) }
}
impl<L: AffineFold<T>, T> AffineFold<T> for &L where Self::View: Sized {
fn preview(&self, s: T) -> Result<L::View, Self::Error> { L::preview(self, s) }
}
impl<'a, L: AffineFoldRef<'a, T>, T: ?Sized + 'a> AffineFoldRef<'a, T> for &L where Self::View: 'a {
fn preview_ref(&self, s: &'a T) -> Result<&'a L::View, Self::Error> { L::preview_ref(self, s) }
}
impl<'a, L: AffineFoldMut<'a, T>, T: ?Sized + 'a> AffineFoldMut<'a, T> for &L where Self::View: 'a {
fn preview_mut(&self, s: &'a mut T) -> Result<&'a mut L::View, Self::Error> { L::preview_mut(self, s) }
}
impl<L: Review<T>, T> Review<T> for &L where Self::View: Sized {
fn review(&self, a: L::View) -> T { L::review(self, a) }
}
impl<L: Setter<T>, T> Setter<T> for &L where Self::View: Sized {
fn over(&self, s: &mut T, f: &mut dyn FnMut(&mut Self::View)) { L::over(self, s, f) }
fn set_cloned(&self, a: &Self::View, s: &mut T) where Self::View: Clone { L::set_cloned(self, a, s) }
}
impl<L: Traversal<T>, T> Traversal<T> for &L where Self::View: Sized {
fn traverse(&self, s: T, f: &mut dyn FnMut(L::View)) { L::traverse(self, s, f) }
fn fold<C>(&self, s: T, init: C, f: impl FnMut(&mut C, Self::View)) -> C { L::fold(self, s, init, f) }
fn flatten(&self, s: T) -> Vec<Self::View> { L::flatten(self, s) }
}
impl<L: AffineTraversal<T>, T> AffineTraversal<T> for &L where Self::View: Sized {
fn map(&self, s: &mut T, f: impl FnOnce(&mut Self::View)) { L::map(self, s, f) }
fn set(&self, s: &mut T, a: Self::View) { L::set(self, s, a) }
}
impl<L: Lens<T>, T> Lens<T> for &L where Self::View: Sized {}
impl<L: Prism<T>, T> Prism<T> for &L where Self::View: Sized {}
impl<L: Iso<T>, T> Iso<T> for &L where Self::View: Sized {}
crate::declare_lens! {
#[derive(Debug)]
pub Identity as T => T, for<T>, (x) => x
}
impl<T> Review<T> for Identity {
fn review(&self, a: T) -> T { a }
}
impl<T> Prism<T> for Identity {}
impl<T> Iso<T> for Identity {}
impl Display for Identity {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("self")
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""))]
#[derivative(Copy(bound = ""), Clone(bound = ""))]
#[derivative(Hash(bound = ""), Eq(bound = ""), PartialEq(bound = ""))]
pub struct _Identity<T: ?Sized>(PhantomData<fn() -> T>);
impl<T: ?Sized> Debug for _Identity<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "_Identity::<{}>", std::any::type_name::<T>())
}
}
impl<T: ?Sized> Display for _Identity<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "self<{}>", std::any::type_name::<T>())
}
}
impl<T: ?Sized> Optics<T> for _Identity<T> { type View = T; }
impl<T: ?Sized> OpticsFallible for _Identity<T> {
type Success = _Identity<T>;
type Error = _Identity<T>;
fn success_witness(&self) -> _Identity<T> { _Identity::default() }
}
impl<T: ?Sized> OpticsKnownSource for _Identity<T> { type Source = T; }
impl<T> Getter<T> for _Identity<T> {
fn view(&self, s: T) -> T { s }
}
impl<'a, T: ?Sized + 'a> GetterRef<'a, T> for _Identity<T> {
fn view_ref(&self, s: &'a T) -> &'a T { s }
}
impl<'a, T: ?Sized + 'a> GetterMut<'a, T> for _Identity<T> {
fn view_mut(&self, s: &'a mut T) -> &'a mut T { s }
}
impl<T> AffineFold<T> for _Identity<T> {
fn preview(&self, s: T) -> Result<T, Self::Error> { Ok(s) }
}
impl<'a, T: ?Sized + 'a> AffineFoldRef<'a, T> for _Identity<T> {
fn preview_ref(&self, s: &'a T) -> Result<&'a T, Self::Error> { Ok(s) }
}
impl<'a, T: ?Sized + 'a> AffineFoldMut<'a, T> for _Identity<T> {
fn preview_mut(&self, s: &'a mut T) -> Result<&'a mut T, Self::Error> { Ok(s) }
}
impl<T> Review<T> for _Identity<T> {
fn review(&self, a: T) -> T { a }
}
impl<T> AffineTraversal<T> for _Identity<T> {
fn map(&self, s: &mut T, f: impl FnOnce(&mut T)) { f(s) }
}
impl<T> Traversal<T> for _Identity<T> {
fn traverse(&self, s: T, f: &mut dyn FnMut(T)) { f(s) }
}
impl<T> Setter<T> for _Identity<T> {
fn over(&self, s: &mut T, f: &mut dyn FnMut(&mut T)) { f(s) }
}
impl<T> Lens<T> for _Identity<T> {}
impl<T> Prism<T> for _Identity<T> {}
impl<T> Iso<T> for _Identity<T> {}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct SuccessCompose<S, R>(S, R);
impl<S: Display, R: Display> Display for SuccessCompose<S, R> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}", self.0, self.1)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ErrorCompose<E, S, R> {
Head(E),
Tail(S, R),
}
impl<E: Display, S: Display, R: Display> Display for ErrorCompose<E, S, R> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ErrorCompose::Head(x) => x.fmt(f),
ErrorCompose::Tail(x, r) => write!(f, "{x}.{r}"),
}
}
}
impl<E, S, R> From<E> for ErrorCompose<E, S, R> {
fn from(err: E) -> Self { ErrorCompose::Head(err) }
}
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct Compose<K, L>(pub K, pub L);
impl<K: Debug, L: Debug> Debug for Compose<K, L> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}.{:?}", self.0, self.1)
}
}
impl<K: Display, L: Display> Display for Compose<K, L> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}", self.0, self.1)
}
}
impl<K: Optics<T>, L: Optics<K::View>, T: ?Sized> Optics<T> for Compose<K, L> {
type View = L::View;
}
impl<K: OpticsFallible, L: OpticsFallible> OpticsFallible for Compose<K, L> {
type Success = SuccessCompose<K::Success, L::Success>;
type Error = ErrorCompose<K::Error, K::Success, L::Error>;
fn success_witness(&self) -> Self::Success {
SuccessCompose(self.0.success_witness(), self.1.success_witness())
}
}
impl<K, L, T> AffineFold<T> for Compose<K, L>
where K: AffineFold<T>, K::View: Sized,
L: AffineFold<K::View>, L::View: Sized {
fn preview(&self, s: T) -> Result<L::View, Self::Error> {
self.1.preview(self.0.preview(s)?)
.map_err(|err| ErrorCompose::Tail(self.0.success_witness(), err))
}
}
impl<'a, T: ?Sized, K, L> AffineFoldRef<'a, T> for Compose<K, L>
where K: AffineFoldRef<'a, T>, K::View: 'a,
L: AffineFoldRef<'a, K::View>, L::View: 'a {
fn preview_ref(&self, s: &'a T) -> Result<&'a L::View, Self::Error> {
self.1.preview_ref(self.0.preview_ref(s)?)
.map_err(|err| ErrorCompose::Tail(self.0.success_witness(), err))
}
}
impl<'a, T: ?Sized, K, L> AffineFoldMut<'a, T> for Compose<K, L>
where K: AffineFoldMut<'a, T>, K::View: 'a,
L: AffineFoldMut<'a, K::View>, L::View: 'a {
fn preview_mut(&self, s: &'a mut T) -> Result<&'a mut L::View, Self::Error> {
self.1.preview_mut(self.0.preview_mut(s)?)
.map_err(|err| ErrorCompose::Tail(self.0.success_witness(), err))
}
}
impl<K, L, T> Getter<T> for Compose<K, L>
where K: Getter<T>, K::View: Sized,
L: Getter<K::View>, L::View: Sized {
fn view(&self, s: T) -> L::View {
self.1.view(self.0.view(s))
}
}
impl<'a, T: ?Sized, K, L> GetterRef<'a, T> for Compose<K, L>
where K: GetterRef<'a, T>, K::View: 'a,
L: GetterRef<'a, K::View>, L::View: 'a {
fn view_ref(&self, s: &'a T) -> &'a L::View {
self.1.view_ref(self.0.view_ref(s))
}
}
impl<'a, T: ?Sized, K, L> GetterMut<'a, T> for Compose<K, L>
where K: GetterMut<'a, T>, K::View: 'a,
L: GetterMut<'a, K::View>, L::View: 'a {
fn view_mut(&self, s: &'a mut T) -> &'a mut L::View {
self.1.view_mut(self.0.view_mut(s))
}
}
impl<K, L, T> Review<T> for Compose<K, L>
where K: Review<T>, K::View: Sized,
L: Review<K::View>, L::View: Sized {
fn review(&self, a: L::View) -> T {
self.0.review(self.1.review(a))
}
}
impl<K, L, T> Iso<T> for Compose<K, L>
where K: Iso<T>, K::View: Sized,
L: Iso<K::View>, L::View: Sized {}
impl<K, L, T> Setter<T> for Compose<K, L>
where K: Setter<T>, K::View: Sized,
L: Setter<K::View>, L::View: Sized {
fn over(&self, s: &mut T, f: &mut dyn FnMut(&mut L::View)) {
self.0.over(s, &mut |c| self.1.over(c, f))
}
}
impl<K, L, T> Traversal<T> for Compose<K, L>
where K: Traversal<T>, K::View: Sized,
L: Traversal<K::View>, L::View: Sized {
fn traverse(&self, s: T, f: &mut dyn FnMut(Self::View)) {
self.0.traverse(s, &mut |v| self.1.traverse(v, f))
}
}
impl<K, L, T> AffineTraversal<T> for Compose<K, L>
where K: AffineTraversal<T>, K::View: Sized,
L: AffineTraversal<K::View>, L::View: Sized {
fn map(&self, s: &mut T, f: impl FnOnce(&mut L::View)) {
self.0.map(s, |v| self.1.map(v, f))
}
}
impl<K, L, T> Lens<T> for Compose<K, L>
where K: Lens<T>, K::View: Sized,
L: Lens<K::View>, L::View: Sized {}
impl<K, L, T> Prism<T> for Compose<K, L>
where K: Prism<T>, K::View: Sized,
L: Prism<K::View>, L::View: Sized {}
pub struct MapFallible<L, F, G>(pub(crate) L, pub(crate) F, pub(crate) G);
pub type MapSuccess<L, F> = MapFallible<L, F, fn(<L as OpticsFallible>::Error) -> <L as OpticsFallible>::Error>;
pub type MapError<L, G> = MapFallible<L, fn(<L as OpticsFallible>::Success) -> <L as OpticsFallible>::Success, G>;
pub type MapFallibleTo<L, S, E> = MapFallible<L,
fn(<L as OpticsFallible>::Success) -> S,
fn(<L as OpticsFallible>::Error) -> E,
>;
impl<T: ?Sized, L: Optics<T>, F, G> Optics<T> for MapFallible<L, F, G> {
type View = L::View;
}
impl<L: OpticsFallible, S, F, E, G> OpticsFallible for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E {
type Success = S;
type Error = E;
fn success_witness(&self) -> S {
(self.1)(self.0.success_witness())
}
}
impl<T, L: AffineFold<T>, S, F, E, G> AffineFold<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {
fn preview(&self, s: T) -> Result<Self::View, E> {
self.0.preview(s).map_err(&self.2)
}
}
impl<'a, T: ?Sized, L: AffineFoldRef<'a, T>, S, F, E, G> AffineFoldRef<'a, T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: 'a {
fn preview_ref(&self, s: &'a T) -> Result<&'a Self::View, E> {
self.0.preview_ref(s).map_err(&self.2)
}
}
impl<'a, T: ?Sized, L: AffineFoldMut<'a, T>, S, F, E, G> AffineFoldMut<'a, T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: 'a {
fn preview_mut(&self, s: &'a mut T) -> Result<&'a mut Self::View, E> {
self.0.preview_mut(s).map_err(&self.2)
}
}
impl<T, L: Getter<T>, S, F, E, G> Getter<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {
fn view(&self, s: T) -> Self::View { self.0.view(s) }
}
impl<'a, T: ?Sized, L: GetterRef<'a, T>, S, F, E, G> GetterRef<'a, T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: 'a {
fn view_ref(&self, s: &'a T) -> &'a Self::View { self.0.view_ref(s) }
}
impl<'a, T: ?Sized, L: GetterMut<'a, T>, S, F, E, G> GetterMut<'a, T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: 'a {
fn view_mut(&self, s: &'a mut T) -> &'a mut Self::View { self.0.view_mut(s) }
}
impl<T, L: Review<T>, F, G> Review<T> for MapFallible<L, F, G> where L::View: Sized {
fn review(&self, a: Self::View) -> T { self.0.review(a) }
}
impl<T, L: Iso<T>, S, F, E, G> Iso<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {}
impl<T, L: Setter<T>, F, G> Setter<T> for MapFallible<L, F, G> where L::View: Sized {
fn over(&self, s: &mut T, f: &mut dyn FnMut(&mut Self::View)) { self.0.over(s, f) }
fn set_cloned(&self, a: &Self::View, s: &mut T) where Self::View: Clone { self.0.set_cloned(a, s) }
}
impl<T, L: Traversal<T>, F, G> Traversal<T> for MapFallible<L, F, G> where L::View: Sized {
fn traverse(&self, s: T, f: &mut dyn FnMut(Self::View)) { self.0.traverse(s, f) }
fn fold<C>(&self, s: T, init: C, f: impl FnMut(&mut C, Self::View)) -> C { self.0.fold(s, init, f) }
fn flatten(&self, s: T) -> Vec<Self::View> { self.0.flatten(s) }
}
impl<T, L: AffineTraversal<T>, S, F, E, G> AffineTraversal<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {
fn map(&self, s: &mut T, f: impl FnOnce(&mut Self::View)) { self.0.map(s, f) }
fn set(&self, s: &mut T, a: Self::View) { self.0.set(s, a) }
}
impl<T, L: Lens<T>, S, F, E, G> Lens<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {}
impl<T, L: Prism<T>, S, F, E, G> Prism<T> for MapFallible<L, F, G>
where F: Fn(L::Success) -> S, G: Fn(L::Error) -> E, L::View: Sized {}
#[macro_export]
macro_rules! optics {
() => { $crate::concrete::Identity };
($single:tt) => { #[allow(unused_parens)]{ $single } };
($head:tt $(. $tail:tt)*) => {
$crate::concrete::Compose(
#[allow(unused_parens)]{ $head },
$crate::optics!($($tail).*),
)
}
}
#[macro_export]
macro_rules! declare_lens {
(
$(#[$m:meta])* $vis:vis
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) => by_val: $by_val:expr, by_ref: $by_ref:expr, by_mut: $by_mut:expr $(,)?
) => {
$(#[$m])*
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
$vis struct $name;
$crate::mark_infallible!($name);
$crate::mark_known_source!($name $(for<$($p),+>)? : $base);
$crate::impl_lens! {
$name as $base => $target $(, for<$($p),+>)?,
($s) => by_val: $by_val, by_ref: $by_ref, by_mut: $by_mut
}
};
(
$(#[$m:meta])* $vis:vis
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) $(reused($wrap:ident))? => $reused:expr $(,)?
) => {
$(#[$m])*
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
$vis struct $name;
$crate::mark_infallible!($name);
$crate::mark_known_source!($name $(for<$($p),+>)? : $base);
$crate::impl_lens! {
$name as $base => $target $(, for<$($p),+>)?,
($s) $(reused($wrap))? => $reused
}
};
}
#[macro_export]
macro_rules! mark_infallible {
($name:ident) => {
impl $crate::traits::OpticsFallible for $name {
type Success = $name;
type Error = std::convert::Infallible;
fn success_witness(&self) -> $name { *self }
}
}
}
#[macro_export]
macro_rules! mark_fallible {
($name:ident) => {
impl $crate::traits::OpticsFallible for $name {
type Success = $name;
type Error = $name;
fn success_witness(&self) -> $name { *self }
}
}
}
#[macro_export]
macro_rules! mark_known_source {
($name:ident: $base:ty) => {
impl $crate::traits::OpticsKnownSource for $name {
type Source = $base;
}
};
($name:ident $(for<$($p:ident),+>)? : $base:ty) => {};
($name:ident if single ($(for<$($p:ident),+>)?, $base:ty)) => {
$crate::mark_known_source!($name $(for<$($p),+>)? : $base);
};
($name:ident if single ($(for<$($p:ident),+>)?, $base:ty;
$($(for<$($p_rest:ident),+>)?, $rest:ty);+)) => {}
}
#[macro_export]
macro_rules! impl_lens {
(
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) => by_val: $by_val:expr, by_ref: $by_ref:expr, by_mut: $by_mut:expr $(,)?
) => {
impl $(<$($p),+>)? $crate::traits::Optics<$base> for $name {
type View = $target;
}
impl $(<$($p),+>)? $crate::traits::Getter<$base> for $name {
fn view(&self, $s: $base) -> $target { $by_val }
}
impl <'a $($(, $p)+)?> $crate::traits::GetterRef<'a, $base> for $name where $target: 'a {
fn view_ref(&self, $s: &'a $base) -> &'a $target { $by_ref }
}
impl <'a $($(, $p)+)?> $crate::traits::GetterMut<'a, $base> for $name where $target: 'a {
fn view_mut(&self, $s: &'a mut $base) -> &'a mut $target { $by_mut }
}
$crate::impl_up_from!([Getter(Ref,Mut)] $name as $base => $target $(, for<$($p),+>)?);
impl $(<$($p),+>)? $crate::traits::Lens<$base> for $name {}
};
(
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) $(reused($wrap:ident))? => $reused:expr $(,)?
) => {
$crate::impl_lens! { $name as $base => $target $(, for<$($p),+>)?, ($s) =>
by_val: { $(macro_rules! $wrap { ($res:expr) => { $res } })? $reused },
by_ref: { $(macro_rules! $wrap { ($res:expr) => { &$res } })? $reused },
by_mut: { $(macro_rules! $wrap { ($res:expr) => { &mut $res } })? $reused },
}
};
}
#[macro_export]
macro_rules! declare_lens_from_field {
($(
$(#[$m:meta])* $vis:vis $name:ident for $field:tt
$(as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?)+
);+ $(;)?) => {$(
$(#[$m])*
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
$vis struct $name;
impl std::fmt::Debug for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const BASES: &[&str] = &[$(stringify!($base)),+];
if BASES.len() == 1 {
f.write_str(BASES[0])?;
} else {
write!(f, "{{{}", BASES[0])?;
for base in BASES.iter().skip(1).take(2) {
write!(f, ",{}", base)?;
}
if BASES.len() > 3 { write!(f, ",..")? }
write!(f, "}}")?;
}
write!(f, "::{}", stringify!($field))
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(stringify!($field))
}
}
$crate::mark_infallible!($name);
$crate::mark_known_source!($name if single ($($(for<$($p),+>)?, $base);+));
$(
$crate::impl_lens! {
$name as $base => $target $(, for<$($p),+>)?,
(s) reused(wrap) => wrap!(s.$field)
}
)+
)+}
}
#[macro_export]
macro_rules! declare_prism_from_variant {
($(
$(#[$m:meta])* $vis:vis $name:ident for $variant:tt
as $base:ident $(<$($p1:ident),+ $(,)?>)? => $target:ty
$(, for <$($p:ident),+ $(,)?>)?
);+ $(;)?) => {$(
$crate::declare_affine_traversal! {
$(#[$m])* $vis $name as $base $(<$($p1),+>)? => $target $(, for<$($p),+>)?,
(s) => if let $base::$variant(x) = s { Ok(x) } else { Err($name) }
}
impl std::fmt::Debug for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}::{}", stringify!($base), stringify!($variant))
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(stringify!($variant))
}
}
impl $(<$($p),+>)? $crate::traits::Review<$base $(<$($p1),+>)?> for $name {
fn review(&self, a: $target) -> $base $(<$($p1),+>)? { $base::$variant(a) }
}
impl $(<$($p),+>)? $crate::traits::Prism<$base $(<$($p1),+>)?> for $name {}
)+}
}
#[macro_export]
macro_rules! declare_affine_traversal {
(
$(#[$m:meta])* $vis:vis
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) => by_val: $by_val:expr, by_ref: $by_ref:expr, by_mut: $by_mut:expr $(,)?
) => {
$(#[$m])*
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
$vis struct $name;
$crate::mark_fallible!($name);
$crate::mark_known_source!($name $(for<$($p),+>)? : $base);
$crate::impl_affine_traversal! {
$name as $base => $target $(, for<$($p),+>)?,
($s) => by_val: $by_val, by_ref: $by_ref, by_mut: $by_mut
}
};
(
$(#[$m:meta])* $vis:vis
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) $(reused($wrap:ident))? => $reused:expr $(,)?
) => {
$(#[$m])*
#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
$vis struct $name;
$crate::mark_fallible!($name);
$crate::mark_known_source!($name $(for<$($p),+>)? : $base);
$crate::impl_affine_traversal! {
$name as $base => $target $(, for<$($p),+>)?,
($s) $(reused($wrap))? => $reused
}
};
}
#[macro_export]
macro_rules! impl_affine_traversal {
(
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) => by_val: $by_val:expr, by_ref: $by_ref:expr, by_mut: $by_mut:expr $(,)?
) => {
impl $(<$($p),+>)? $crate::traits::Optics<$base> for $name {
type View = $target;
}
impl $(<$($p),+>)? $crate::traits::AffineFold<$base> for $name {
fn preview(&self, $s: $base) -> Result<$target, Self::Error> { $by_val }
}
impl <'a $($(, $p)+)?> $crate::traits::AffineFoldRef<'a, $base> for $name where $target: 'a {
fn preview_ref(&self, $s: &'a $base) -> Result<&'a $target, Self::Error> { $by_ref }
}
impl <'a $($(, $p)+)?> $crate::traits::AffineFoldMut<'a, $base> for $name where $target: 'a {
fn preview_mut(&self, $s: &'a mut $base) -> Result<&'a mut $target, Self::Error> { $by_mut }
}
$crate::impl_up_from!([AffineFold(Mut)] $name as $base => $target $(, for<$($p),+>)?);
};
(
$name:ident as $base:ty => $target:ty $(, for<$($p:ident),+ $(,)?>)?,
($s:ident) $(reused($wrap:ident))? => $reused:expr $(,)?
) => {
$crate::impl_affine_traversal! {
$name as $base => $target $(, for<$($p),+>)?, ($s) =>
by_val: { $(macro_rules! $wrap { ($res:expr) => { $res } })? $reused },
by_ref: { $(macro_rules! $wrap { ($res:expr) => { &$res } })? $reused },
by_mut: { $(macro_rules! $wrap { ($res:expr) => { &mut $res } })? $reused },
}
};
}
#[macro_export]
macro_rules! impl_up_from {
(
[AffineTraversal]
$(
$name:ident as $base:ty => $target:ty
$(, for <$($p:ident),+ $(,)?>)?
);+ $(;)?
) => {$(
impl $(<$($p),+>)? $crate::traits::Setter<$base> for $name {
fn over(&self, s: &mut $base, f: &mut dyn FnMut(&mut $target)) {
$crate::traits::AffineTraversal::map(self, s, f)
}
}
)+};
(
[AffineFold(Mut)]
$(
$name:ident as $base:ty => $target:ty
$(, for <$($p:ident),+ $(,)?>)?
);+ $(;)?
) => {$(
impl $(<$($p),+>)? $crate::traits::Traversal<$base> for $name {
fn traverse(&self, s: $base, f: &mut dyn FnMut($target)) {
let _ = $crate::traits::AffineFold::preview(self, s).map(f);
}
}
impl $(<$($p),+>)? $crate::traits::AffineTraversal<$base> for $name {
fn map(&self, s: &mut $base, f: impl FnOnce(&mut $target)) {
let _ = $crate::traits::AffineFoldMut::preview_mut(self, s).map(f);
}
}
$crate::impl_up_from!([AffineTraversal] $name as $base => $target $(, for<$($p),+>)?);
)+};
(
[Getter(Ref,Mut)]
$(
$name:ident as $base:ty => $target:ty
$(, for <$($p:ident),+ $(,)?>)?
);+ $(;)?
) => {$(
impl $(<$($p),+>)? $crate::traits::AffineFold<$base> for $name {
fn preview(&self, s: $base) -> Result<$target, Self::Error> {
Ok($crate::traits::Getter::view(self, s))
}
}
impl <'a $($(, $p)+)?> $crate::traits::AffineFoldRef<'a, $base> for $name where $target: 'a {
fn preview_ref(&self, s: &'a $base) -> Result<&'a $target, Self::Error> {
Ok($crate::traits::GetterRef::view_ref(self, s))
}
}
impl <'a $($(, $p)+)?> $crate::traits::AffineFoldMut<'a, $base> for $name where $target: 'a {
fn preview_mut(&self, s: &'a mut $base) -> Result<&'a mut $target, Self::Error> {
Ok($crate::traits::GetterMut::view_mut(self, s))
}
}
$crate::impl_up_from!([AffineFold(Mut)] $name as $base => $target $(, for<$($p),+>)?);
)+};
}