split optics wrapper type into Lens, Traversal, Prism
parent
e5a9293ec2
commit
f73c2ad5b6
|
@ -1,21 +1,13 @@
|
||||||
use crate::{
|
use crate::lenses::{Lens, LensOver, LensView};
|
||||||
lenses::{LensOver, LensView},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Combination<A, B>(A, B);
|
pub struct Combination<A, B>(A, B);
|
||||||
impl<A, B> OpticsTrait for Combination<A, B> {}
|
|
||||||
|
|
||||||
impl<A, B> std::ops::Add<Optics<B>> for Optics<A>
|
impl<A, B> std::ops::Add<Lens<B>> for Lens<A> {
|
||||||
where
|
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
|
||||||
A: OpticsTrait,
|
|
||||||
B: OpticsTrait,
|
|
||||||
{
|
|
||||||
type Output = Optics<Combination<Optics<A>, Optics<B>>>;
|
|
||||||
|
|
||||||
fn add(self, rhs: Optics<B>) -> Self::Output {
|
fn add(self, rhs: Lens<B>) -> Self::Output {
|
||||||
Optics(Combination(self, rhs))
|
Lens(Combination(self, rhs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
77
src/fns.rs
77
src/fns.rs
|
@ -1,9 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
lenses::{LensOver, LensView},
|
lenses::{Lens, LensOver, LensView},
|
||||||
Optics,
|
traversals::{Traversal, TraversalOver, TraversalTraverse},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<L, A> std::ops::FnOnce<(A,)> for Optics<L>
|
// lens view
|
||||||
|
impl<L, A> std::ops::FnOnce<(A,)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensView<A>,
|
L: LensView<A>,
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ where
|
||||||
L::view(&self.0, args.0)
|
L::view(&self.0, args.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, A> std::ops::FnMut<(A,)> for Optics<L>
|
impl<L, A> std::ops::FnMut<(A,)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensView<A>,
|
L: LensView<A>,
|
||||||
{
|
{
|
||||||
|
@ -21,7 +22,7 @@ where
|
||||||
L::view(&self.0, args.0)
|
L::view(&self.0, args.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, A> std::ops::Fn<(A,)> for Optics<L>
|
impl<L, A> std::ops::Fn<(A,)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensView<A>,
|
L: LensView<A>,
|
||||||
{
|
{
|
||||||
|
@ -30,7 +31,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L, A, F> std::ops::FnOnce<(A, F)> for Optics<L>
|
// lens over
|
||||||
|
impl<L, A, F> std::ops::FnOnce<(A, F)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensOver<A>,
|
L: LensOver<A>,
|
||||||
F: FnOnce(L::Field) -> L::Field,
|
F: FnOnce(L::Field) -> L::Field,
|
||||||
|
@ -41,7 +43,7 @@ where
|
||||||
L::over(&self.0, args.0, args.1)
|
L::over(&self.0, args.0, args.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, A, F> std::ops::FnMut<(A, F)> for Optics<L>
|
impl<L, A, F> std::ops::FnMut<(A, F)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensOver<A>,
|
L: LensOver<A>,
|
||||||
F: FnOnce(L::Field) -> L::Field,
|
F: FnOnce(L::Field) -> L::Field,
|
||||||
|
@ -50,7 +52,7 @@ where
|
||||||
L::over(&self.0, args.0, args.1)
|
L::over(&self.0, args.0, args.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, A, F> std::ops::Fn<(A, F)> for Optics<L>
|
impl<L, A, F> std::ops::Fn<(A, F)> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensOver<A>,
|
L: LensOver<A>,
|
||||||
F: FnOnce(L::Field) -> L::Field,
|
F: FnOnce(L::Field) -> L::Field,
|
||||||
|
@ -59,3 +61,62 @@ where
|
||||||
L::over(&self.0, args.0, args.1)
|
L::over(&self.0, args.0, args.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// traversal traverse
|
||||||
|
impl<L, A> std::ops::FnOnce<(A,)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalTraverse<A>,
|
||||||
|
{
|
||||||
|
type Output = Vec<L::Field>;
|
||||||
|
|
||||||
|
extern "rust-call" fn call_once(self, args: (A,)) -> Self::Output {
|
||||||
|
L::traverse(&self.0, args.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<L, A> std::ops::FnMut<(A,)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalTraverse<A>,
|
||||||
|
{
|
||||||
|
extern "rust-call" fn call_mut(&mut self, args: (A,)) -> Self::Output {
|
||||||
|
L::traverse(&self.0, args.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<L, A> std::ops::Fn<(A,)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalTraverse<A>,
|
||||||
|
{
|
||||||
|
extern "rust-call" fn call(&self, args: (A,)) -> Self::Output {
|
||||||
|
L::traverse(&self.0, args.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// traversal over
|
||||||
|
impl<L, A, F> std::ops::FnOnce<(A, F)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalOver<A>,
|
||||||
|
F: FnMut(L::Field) -> L::Field,
|
||||||
|
{
|
||||||
|
type Output = A;
|
||||||
|
|
||||||
|
extern "rust-call" fn call_once(self, args: (A, F)) -> Self::Output {
|
||||||
|
L::over(&self.0, args.0, args.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<L, A, F> std::ops::FnMut<(A, F)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalOver<A>,
|
||||||
|
F: FnMut(L::Field) -> L::Field,
|
||||||
|
{
|
||||||
|
extern "rust-call" fn call_mut(&mut self, args: (A, F)) -> Self::Output {
|
||||||
|
L::over(&self.0, args.0, args.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<L, A, F> std::ops::Fn<(A, F)> for Traversal<L>
|
||||||
|
where
|
||||||
|
L: TraversalOver<A>,
|
||||||
|
F: FnMut(L::Field) -> L::Field,
|
||||||
|
{
|
||||||
|
extern "rust-call" fn call(&self, args: (A, F)) -> Self::Output {
|
||||||
|
L::over(&self.0, args.0, args.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use crate::{
|
use crate::lenses::{Lens, LensOver, LensView};
|
||||||
lenses::{LensOver, LensView},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct _0Inner;
|
pub struct _0Inner;
|
||||||
pub const _0: Optics<_0Inner> = Optics(_0Inner);
|
pub const _0: Lens<_0Inner> = Lens(_0Inner);
|
||||||
impl OpticsTrait for _0Inner {}
|
|
||||||
|
|
||||||
macro_rules! make_tuples {
|
macro_rules! make_tuples {
|
||||||
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
use crate::{
|
use crate::lenses::{Lens, LensOver, LensView};
|
||||||
lenses::{LensOver, LensView},
|
|
||||||
OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct id;
|
pub struct IdInner;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const id: Lens<IdInner> = Lens(IdInner);
|
||||||
|
|
||||||
impl OpticsTrait for id {}
|
impl<T> LensView<T> for IdInner {
|
||||||
impl<T> LensView<T> for id {
|
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
||||||
fn view(&self, thing: T) -> Self::Field {
|
fn view(&self, thing: T) -> Self::Field {
|
||||||
thing
|
thing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> LensOver<T> for id {
|
impl<T> LensOver<T> for IdInner {
|
||||||
fn over<F>(&self, thing: T, f: F) -> T
|
fn over<F>(&self, thing: T, f: F) -> T
|
||||||
where
|
where
|
||||||
F: FnOnce(Self::Field) -> Self::Field,
|
F: FnOnce(Self::Field) -> Self::Field,
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use crate::{
|
use crate::lenses::{Lens, LensOver, LensView};
|
||||||
lenses::{LensOver, LensView},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
type Getter<T, U> = dyn Fn(T) -> U;
|
type Getter<T, U> = dyn Fn(T) -> U;
|
||||||
type Setter<T, U> = dyn Fn(T, U) -> T;
|
type Setter<T, U> = dyn Fn(T, U) -> T;
|
||||||
|
|
||||||
pub struct LensInner<T, U>(pub(crate) Box<Getter<T, U>>, pub(crate) Box<Setter<T, U>>);
|
pub struct LensInner<T, U>(pub(crate) Box<Getter<T, U>>, pub(crate) Box<Setter<T, U>>);
|
||||||
impl<T, U> OpticsTrait for LensInner<T, U> {}
|
|
||||||
|
|
||||||
impl<T, U> LensView<T> for LensInner<T, U> {
|
impl<T, U> LensView<T> for LensInner<T, U> {
|
||||||
type Field = U;
|
type Field = U;
|
||||||
|
@ -34,13 +30,13 @@ impl<T: Clone, U> LensOver<T> for LensInner<T, U> {
|
||||||
pub fn lens_from_boxed<T, U>(
|
pub fn lens_from_boxed<T, U>(
|
||||||
getter: Box<Getter<T, U>>,
|
getter: Box<Getter<T, U>>,
|
||||||
setter: Box<Setter<T, U>>,
|
setter: Box<Setter<T, U>>,
|
||||||
) -> Optics<LensInner<T, U>> {
|
) -> Lens<LensInner<T, U>> {
|
||||||
Optics(LensInner(getter, setter))
|
Lens(LensInner(getter, setter))
|
||||||
}
|
}
|
||||||
/// Makes a lens that implements `LensView<T>` and `LensOver<T>` with the provided functions
|
/// Makes a lens that implements `LensView<T>` and `LensOver<T>` with the provided functions
|
||||||
pub fn lens<T, U>(
|
pub fn lens<T, U>(
|
||||||
getter: impl Fn(T) -> U + 'static,
|
getter: impl Fn(T) -> U + 'static,
|
||||||
setter: impl Fn(T, U) -> T + 'static,
|
setter: impl Fn(T, U) -> T + 'static,
|
||||||
) -> Optics<LensInner<T, U>> {
|
) -> Lens<LensInner<T, U>> {
|
||||||
Optics(LensInner(Box::new(getter), Box::new(setter)))
|
Lens(LensInner(Box::new(getter), Box::new(setter)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,30 @@ pub use to::{to, to_from_boxed};
|
||||||
mod lens;
|
mod lens;
|
||||||
pub use lens::{lens, lens_from_boxed};
|
pub use lens::{lens, lens_from_boxed};
|
||||||
|
|
||||||
use crate::{Optics, OpticsTrait};
|
use crate::traversals::Traversal;
|
||||||
|
|
||||||
|
/// Wrapper type
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Lens<L>(pub(crate) L);
|
||||||
|
|
||||||
|
// all lenses are traversals, so we can freely transform them into a traversal
|
||||||
|
impl<L> Lens<L> {
|
||||||
|
/// Returns this lens as a traversal
|
||||||
|
pub fn to_traversal(self) -> Traversal<Lens<L>> {
|
||||||
|
Traversal(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we can go back to a lens from a "traversal-ed" lens
|
||||||
|
impl<L> Traversal<Lens<L>> {
|
||||||
|
/// Returns the wrapped lens
|
||||||
|
pub fn to_lens(self) -> Lens<L> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// For lenses that allow viewing
|
/// For lenses that allow viewing
|
||||||
pub trait LensView<T>: OpticsTrait {
|
pub trait LensView<T> {
|
||||||
type Field;
|
type Field;
|
||||||
|
|
||||||
fn view(&self, thing: T) -> Self::Field;
|
fn view(&self, thing: T) -> Self::Field;
|
||||||
|
@ -31,7 +51,7 @@ pub trait LensOver<T>: LensView<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L, T> LensView<T> for Optics<L>
|
impl<L, T> LensView<T> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensView<T>,
|
L: LensView<T>,
|
||||||
{
|
{
|
||||||
|
@ -41,7 +61,7 @@ where
|
||||||
L::view(&self.0, thing)
|
L::view(&self.0, thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, T> LensOver<T> for Optics<L>
|
impl<L, T> LensOver<T> for Lens<L>
|
||||||
where
|
where
|
||||||
L: LensOver<T>,
|
L: LensOver<T>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
use crate::{
|
use crate::lenses::{Lens, LensOver, LensView};
|
||||||
lenses::{LensOver, LensView},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct _1Inner;
|
pub struct _1Inner;
|
||||||
pub const _1: Optics<_1Inner> = Optics(_1Inner);
|
pub const _1: Lens<_1Inner> = Lens(_1Inner);
|
||||||
impl OpticsTrait for _1Inner {}
|
|
||||||
|
|
||||||
macro_rules! make_tuples {
|
macro_rules! make_tuples {
|
||||||
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||||
impl< $($t,)* > LensView<( $($t,)* )> for _1Inner {
|
impl< $($t,)* > LensView<( $($t,)* )> for _1Inner {
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
||||||
fn view(&self, ( $($v,)* ): ($($t,)*)) -> Self::Field {
|
fn view(&self, ( $($v,)* ): ($($t,)*)) -> Self::Field {
|
||||||
$f
|
$f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl< $($t,)* > LensOver<( $($t,)* )> for _1Inner {
|
impl< $($t,)* > LensOver<( $($t,)* )> for _1Inner {
|
||||||
fn over<F>(
|
fn over<F>(
|
||||||
&self,
|
&self,
|
||||||
mut tup: ($($t,)*),
|
mut tup: ($($t,)*),
|
||||||
|
@ -31,14 +27,14 @@ macro_rules! make_tuples {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _1Inner {
|
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _1Inner {
|
||||||
type Field = &'a T;
|
type Field = &'a T;
|
||||||
|
|
||||||
fn view(&self, ( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
|
fn view(&self, ( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
|
||||||
$f
|
$f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _1Inner {
|
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _1Inner {
|
||||||
type Field = &'a mut T;
|
type Field = &'a mut T;
|
||||||
|
|
||||||
fn view(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
|
fn view(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::{lenses::LensView, Optics, OpticsTrait};
|
use crate::lenses::{Lens, LensView};
|
||||||
|
|
||||||
use super::lens::LensInner;
|
use super::lens::LensInner;
|
||||||
|
|
||||||
pub struct ToInner<T, U>(Box<dyn Fn(T) -> U>);
|
pub struct ToInner<T, U>(Box<dyn Fn(T) -> U>);
|
||||||
impl<T, U> OpticsTrait for ToInner<T, U> {}
|
|
||||||
|
|
||||||
impl<T, U> LensView<T> for ToInner<T, U> {
|
impl<T, U> LensView<T> for ToInner<T, U> {
|
||||||
type Field = U;
|
type Field = U;
|
||||||
|
@ -14,17 +13,17 @@ impl<T, U> LensView<T> for ToInner<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a lens that implements `LensView<T>` with the provided function
|
/// Makes a lens that implements `LensView<T>` with the provided function
|
||||||
pub fn to_from_boxed<T, U>(f: Box<dyn Fn(T) -> U>) -> Optics<ToInner<T, U>> {
|
pub fn to_from_boxed<T, U>(f: Box<dyn Fn(T) -> U>) -> Lens<ToInner<T, U>> {
|
||||||
Optics(ToInner(f))
|
Lens(ToInner(f))
|
||||||
}
|
}
|
||||||
/// Makes a lens that implements `LensView<T>` with the provided function
|
/// Makes a lens that implements `LensView<T>` with the provided function
|
||||||
pub fn to<T, U>(f: impl Fn(T) -> U + 'static) -> Optics<ToInner<T, U>> {
|
pub fn to<T, U>(f: impl Fn(T) -> U + 'static) -> Lens<ToInner<T, U>> {
|
||||||
Optics(ToInner(Box::new(f)))
|
Lens(ToInner(Box::new(f)))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> Optics<ToInner<T, U>> {
|
impl<T, U> Lens<ToInner<T, U>> {
|
||||||
/// Makes a full lens that implements `LensView<T>` and `LensOver<T>` with the provided functions
|
/// Makes a full lens that implements `LensView<T>` and `LensOver<T>` with the provided functions
|
||||||
pub fn make_lens(self, setter: impl Fn(T, U) -> T + 'static) -> Optics<LensInner<T, U>> {
|
pub fn make_lens(self, setter: impl Fn(T, U) -> T + 'static) -> Lens<LensInner<T, U>> {
|
||||||
Optics(LensInner((self.0).0, Box::new(setter)))
|
Lens(LensInner((self.0).0, Box::new(setter)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
#![feature(unboxed_closures, fn_traits)]
|
#![feature(unboxed_closures, fn_traits)]
|
||||||
|
|
||||||
/// Base trait
|
|
||||||
pub trait OpticsTrait {}
|
|
||||||
|
|
||||||
/// Wrapper type
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct Optics<T: OpticsTrait>(pub(crate) T);
|
|
||||||
impl<L: OpticsTrait> OpticsTrait for Optics<L> {}
|
|
||||||
|
|
||||||
mod combinations;
|
mod combinations;
|
||||||
mod fns;
|
mod fns;
|
||||||
pub mod lenses;
|
pub mod lenses;
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
use crate::{Optics, OpticsTrait};
|
mod result;
|
||||||
|
pub use result::{_Err, _Ok};
|
||||||
|
|
||||||
pub trait PrismPreview<T>: OpticsTrait {
|
mod option;
|
||||||
|
pub use option::{_None, _Some};
|
||||||
|
|
||||||
|
/// Wrapper type
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Prism<P>(pub(crate) P);
|
||||||
|
|
||||||
|
pub trait PrismPreview<T> {
|
||||||
type Field;
|
type Field;
|
||||||
|
|
||||||
fn preview(thing: T) -> Option<Self::Field>;
|
fn preview(thing: T) -> Option<Self::Field>;
|
||||||
|
@ -9,7 +18,7 @@ pub trait PrismReview<T>: PrismPreview<T> {
|
||||||
fn review(thing: Self::Field) -> T;
|
fn review(thing: Self::Field) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, T> PrismPreview<T> for Optics<P>
|
impl<P, T> PrismPreview<T> for Prism<P>
|
||||||
where
|
where
|
||||||
P: PrismPreview<T>,
|
P: PrismPreview<T>,
|
||||||
{
|
{
|
||||||
|
@ -20,7 +29,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, T> PrismReview<T> for Optics<P>
|
impl<P, T> PrismReview<T> for Prism<P>
|
||||||
where
|
where
|
||||||
P: PrismReview<T>,
|
P: PrismReview<T>,
|
||||||
{
|
{
|
||||||
|
@ -36,12 +45,6 @@ pub fn review<T, P: PrismReview<T>>(_prism: P, thing: P::Field) -> T {
|
||||||
P::review(thing)
|
P::review(thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
mod result;
|
|
||||||
pub use result::{_Err, _Ok};
|
|
||||||
|
|
||||||
mod option;
|
|
||||||
pub use option::{_None, _Some};
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -3,8 +3,8 @@ use super::*;
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct SomeInner;
|
pub struct SomeInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const _Some: Optics<SomeInner> = Optics(SomeInner);
|
pub const _Some: Prism<SomeInner> = Prism(SomeInner);
|
||||||
impl OpticsTrait for SomeInner {}
|
|
||||||
impl<T> PrismPreview<Option<T>> for SomeInner {
|
impl<T> PrismPreview<Option<T>> for SomeInner {
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@ impl<T> PrismReview<Option<T>> for SomeInner {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct NoneInner;
|
pub struct NoneInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const _None: Optics<NoneInner> = Optics(NoneInner);
|
pub const _None: Prism<NoneInner> = Prism(NoneInner);
|
||||||
impl OpticsTrait for NoneInner {}
|
|
||||||
impl<T> PrismPreview<Option<T>> for NoneInner {
|
impl<T> PrismPreview<Option<T>> for NoneInner {
|
||||||
type Field = ();
|
type Field = ();
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ use super::*;
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct OkInner;
|
pub struct OkInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const _Ok: Optics<OkInner> = Optics(OkInner);
|
pub const _Ok: Prism<OkInner> = Prism(OkInner);
|
||||||
impl OpticsTrait for OkInner {}
|
|
||||||
impl<T, E> PrismPreview<Result<T, E>> for OkInner {
|
impl<T, E> PrismPreview<Result<T, E>> for OkInner {
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
||||||
|
@ -22,9 +21,7 @@ impl<T, E> PrismReview<Result<T, E>> for OkInner {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct ErrInner;
|
pub struct ErrInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const _Err: Optics<ErrInner> = Optics(ErrInner);
|
pub const _Err: Prism<ErrInner> = Prism(ErrInner);
|
||||||
|
|
||||||
impl OpticsTrait for ErrInner {}
|
|
||||||
|
|
||||||
impl<T, E> PrismPreview<Result<T, E>> for ErrInner {
|
impl<T, E> PrismPreview<Result<T, E>> for ErrInner {
|
||||||
type Field = E;
|
type Field = E;
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use crate::{
|
use crate::traversals::{Traversal, TraversalOver, TraversalTraverse};
|
||||||
traversals::{TraversalOver, TraversalTraverse},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct BothInner;
|
pub struct BothInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const both: Optics<BothInner> = Optics(BothInner);
|
pub const both: Traversal<BothInner> = Traversal(BothInner);
|
||||||
impl OpticsTrait for BothInner {}
|
|
||||||
|
|
||||||
impl<T> TraversalTraverse<(T, T)> for BothInner {
|
impl<T> TraversalTraverse<(T, T)> for BothInner {
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use crate::{
|
use crate::traversals::{Traversal, TraversalOver, TraversalTraverse};
|
||||||
traversals::{TraversalOver, TraversalTraverse},
|
|
||||||
Optics, OpticsTrait,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct EachInner;
|
pub struct EachInner;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const each: Optics<EachInner> = Optics(EachInner);
|
pub const each: Traversal<EachInner> = Traversal(EachInner);
|
||||||
impl OpticsTrait for EachInner {}
|
|
||||||
|
|
||||||
impl<T> TraversalTraverse<Vec<T>> for EachInner {
|
impl<T> TraversalTraverse<Vec<T>> for EachInner {
|
||||||
type Field = T;
|
type Field = T;
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
use crate::{Optics, OpticsTrait};
|
|
||||||
|
|
||||||
mod both;
|
mod both;
|
||||||
pub use both::both;
|
pub use both::both;
|
||||||
|
|
||||||
mod each;
|
mod each;
|
||||||
pub use each::each;
|
pub use each::each;
|
||||||
|
|
||||||
/// For lenses that allow viewing
|
/// Wrapper type
|
||||||
pub trait TraversalTraverse<T>: OpticsTrait {
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Traversal<T>(pub(crate) T);
|
||||||
|
|
||||||
|
pub trait TraversalTraverse<T> {
|
||||||
type Field;
|
type Field;
|
||||||
|
|
||||||
fn traverse(&self, thing: T) -> Vec<Self::Field>;
|
fn traverse(&self, thing: T) -> Vec<Self::Field>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For lenses that allow setting
|
|
||||||
pub trait TraversalOver<T>: TraversalTraverse<T> {
|
pub trait TraversalOver<T>: TraversalTraverse<T> {
|
||||||
fn over<F>(&self, thing: T, f: F) -> T
|
fn over<F>(&self, thing: T, f: F) -> T
|
||||||
where
|
where
|
||||||
|
@ -26,7 +27,7 @@ pub trait TraversalOver<T>: TraversalTraverse<T> {
|
||||||
Self::over(self, thing, move |_| v.clone())
|
Self::over(self, thing, move |_| v.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, T> TraversalTraverse<T> for Optics<L>
|
impl<L, T> TraversalTraverse<T> for Traversal<L>
|
||||||
where
|
where
|
||||||
L: TraversalTraverse<T>,
|
L: TraversalTraverse<T>,
|
||||||
{
|
{
|
||||||
|
@ -36,7 +37,7 @@ where
|
||||||
L::traverse(&self.0, thing)
|
L::traverse(&self.0, thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<L, T> TraversalOver<T> for Optics<L>
|
impl<L, T> TraversalOver<T> for Traversal<L>
|
||||||
where
|
where
|
||||||
L: TraversalOver<T>,
|
L: TraversalOver<T>,
|
||||||
{
|
{
|
||||||
|
@ -48,29 +49,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // every lens is also a traversal
|
|
||||||
// impl<L, T> TraversalTraverse<T> for Optics<L>
|
|
||||||
// where
|
|
||||||
// L: LensView<T>,
|
|
||||||
// {
|
|
||||||
// type Field = L::Field;
|
|
||||||
|
|
||||||
// fn traverse(&self, thing: T) -> Vec<Self::Field> {
|
|
||||||
// vec![L::view(&self.0, thing)]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// impl<L, T> TraversalOver<T> for Optics<L>
|
|
||||||
// where
|
|
||||||
// L: LensOver<T>,
|
|
||||||
// {
|
|
||||||
// fn over<F>(&self, thing: T, f: F) -> T
|
|
||||||
// where
|
|
||||||
// F: FnMut(Self::Field) -> Self::Field,
|
|
||||||
// {
|
|
||||||
// L::over(&self.0, thing, f)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn traverse<T, L: TraversalTraverse<T>>(lens: L, thing: T) -> Vec<L::Field> {
|
pub fn traverse<T, L: TraversalTraverse<T>>(lens: L, thing: T) -> Vec<L::Field> {
|
||||||
L::traverse(&lens, thing)
|
L::traverse(&lens, thing)
|
||||||
}
|
}
|
||||||
|
@ -92,7 +70,7 @@ mod tests {
|
||||||
fn traverse_each_works_on_arrays() {
|
fn traverse_each_works_on_arrays() {
|
||||||
let array = [1, 2, 3, 4];
|
let array = [1, 2, 3, 4];
|
||||||
|
|
||||||
let res = over(each, array, |v| v + 1);
|
let res = each(array, |v| v + 1);
|
||||||
assert_eq!(res, [2, 3, 4, 5]);
|
assert_eq!(res, [2, 3, 4, 5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue