add prisms
parent
037440c845
commit
ea617b8789
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
lenses::{LensOver, LensView},
|
lenses::{LensOver, LensView},
|
||||||
|
prisms::PrismPreview,
|
||||||
Optics, OpticsTrait,
|
Optics, OpticsTrait,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,3 +44,15 @@ where
|
||||||
A::over(thing, |b| B::over(b, f))
|
A::over(thing, |b| B::over(b, f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, B, T> PrismPreview<T> for Combination<A, B>
|
||||||
|
where
|
||||||
|
A: LensView<T>,
|
||||||
|
B: PrismPreview<A::Field>,
|
||||||
|
{
|
||||||
|
type Field = B::Field;
|
||||||
|
|
||||||
|
fn preview(thing: T) -> Option<Self::Field> {
|
||||||
|
B::preview(A::view(thing))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -57,3 +57,106 @@ pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
|
||||||
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
|
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
|
||||||
L::over(thing, f)
|
L::over(thing, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_first_from_tuple() {
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(view(_0, a), 1);
|
||||||
|
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(view(_0, &a), &1);
|
||||||
|
|
||||||
|
let mut a = (1, 2);
|
||||||
|
assert_eq!(view(_0, &mut a), &mut 1);
|
||||||
|
|
||||||
|
let a = (1, 2, 3);
|
||||||
|
assert_eq!(view(_0, a), 1);
|
||||||
|
|
||||||
|
let a = (1, 2, 3);
|
||||||
|
assert_eq!(view(_0, &a), &1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_first_from_tuple_mut_works() {
|
||||||
|
let mut a = (1, 2);
|
||||||
|
*view(_0, &mut a) += 1;
|
||||||
|
|
||||||
|
assert_eq!(a, (2, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_first_from_tuple() {
|
||||||
|
let a = (1, 2);
|
||||||
|
let a = set(_0, a, 3);
|
||||||
|
assert_eq!(a, (3, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn over_first_from_tuple() {
|
||||||
|
let a = (1, 2);
|
||||||
|
let a = over(_0, a, |v| v + 1);
|
||||||
|
assert_eq!(a, (2, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn over_first_from_array() {
|
||||||
|
let a = [1, 2, 3, 4];
|
||||||
|
|
||||||
|
let a = over(_0, a, |v| v + 1);
|
||||||
|
assert_eq!(a, [2, 2, 3, 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn second() {
|
||||||
|
let a = (1, 2);
|
||||||
|
let a = over(_1, a, |v| v + 1);
|
||||||
|
assert_eq!(a, (1, 3));
|
||||||
|
|
||||||
|
let a = [1, 2, 3, 4];
|
||||||
|
let a = over(_1, a, |v| v + 1);
|
||||||
|
assert_eq!(a, [1, 3, 3, 4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_combination() {
|
||||||
|
let a = ((1, 2), 3);
|
||||||
|
|
||||||
|
let lens = _0 + _1;
|
||||||
|
let a = view(lens, a);
|
||||||
|
assert_eq!(a, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn over_combination() {
|
||||||
|
let a = ((1, 2), 3);
|
||||||
|
|
||||||
|
let lens = _0 + _1;
|
||||||
|
let a = over(lens, a, |v| v + 1);
|
||||||
|
assert_eq!(a, ((1, 3), 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn call_as_funcs() {
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(_0(a), 1);
|
||||||
|
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(_0(a, |v| v + 1), (2, 2));
|
||||||
|
|
||||||
|
let a = ((1, 2), 3);
|
||||||
|
|
||||||
|
let res = _0(a);
|
||||||
|
assert_eq!(res, (1, 2));
|
||||||
|
|
||||||
|
let lens = _0 + _1;
|
||||||
|
|
||||||
|
let res = lens(a);
|
||||||
|
assert_eq!(res, 2);
|
||||||
|
let res = lens(a, |v| v + 1);
|
||||||
|
assert_eq!(res, ((1, 3), 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
104
src/lib.rs
104
src/lib.rs
|
@ -21,106 +21,4 @@ impl<L: OpticsTrait> OpticsTrait for Optics<L> {}
|
||||||
mod combinations;
|
mod combinations;
|
||||||
mod fns;
|
mod fns;
|
||||||
pub mod lenses;
|
pub mod lenses;
|
||||||
|
pub mod prisms;
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::lenses::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn view_first_from_tuple() {
|
|
||||||
let a = (1, 2);
|
|
||||||
assert_eq!(view(_0, a), 1);
|
|
||||||
|
|
||||||
let a = (1, 2);
|
|
||||||
assert_eq!(view(_0, &a), &1);
|
|
||||||
|
|
||||||
let mut a = (1, 2);
|
|
||||||
assert_eq!(view(_0, &mut a), &mut 1);
|
|
||||||
|
|
||||||
let a = (1, 2, 3);
|
|
||||||
assert_eq!(view(_0, a), 1);
|
|
||||||
|
|
||||||
let a = (1, 2, 3);
|
|
||||||
assert_eq!(view(_0, &a), &1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn view_first_from_tuple_mut_works() {
|
|
||||||
let mut a = (1, 2);
|
|
||||||
*view(_0, &mut a) += 1;
|
|
||||||
|
|
||||||
assert_eq!(a, (2, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn set_first_from_tuple() {
|
|
||||||
let a = (1, 2);
|
|
||||||
let a = set(_0, a, 3);
|
|
||||||
assert_eq!(a, (3, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn over_first_from_tuple() {
|
|
||||||
let a = (1, 2);
|
|
||||||
let a = over(_0, a, |v| v + 1);
|
|
||||||
assert_eq!(a, (2, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn over_first_from_array() {
|
|
||||||
let a = [1, 2, 3, 4];
|
|
||||||
|
|
||||||
let a = over(_0, a, |v| v + 1);
|
|
||||||
assert_eq!(a, [2, 2, 3, 4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn second() {
|
|
||||||
let a = (1, 2);
|
|
||||||
let a = over(_1, a, |v| v + 1);
|
|
||||||
assert_eq!(a, (1, 3));
|
|
||||||
|
|
||||||
let a = [1, 2, 3, 4];
|
|
||||||
let a = over(_1, a, |v| v + 1);
|
|
||||||
assert_eq!(a, [1, 3, 3, 4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn view_combination() {
|
|
||||||
let a = ((1, 2), 3);
|
|
||||||
|
|
||||||
let lens = _0 + _1;
|
|
||||||
let a = view(lens, a);
|
|
||||||
assert_eq!(a, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn over_combination() {
|
|
||||||
let a = ((1, 2), 3);
|
|
||||||
|
|
||||||
let lens = _0 + _1;
|
|
||||||
let a = over(lens, a, |v| v + 1);
|
|
||||||
assert_eq!(a, ((1, 3), 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn call_as_funcs() {
|
|
||||||
let a = (1, 2);
|
|
||||||
assert_eq!(_0(a), 1);
|
|
||||||
|
|
||||||
let a = (1, 2);
|
|
||||||
assert_eq!(_0(a, |v| v + 1), (2, 2));
|
|
||||||
|
|
||||||
let a = ((1, 2), 3);
|
|
||||||
|
|
||||||
let res = _0(a);
|
|
||||||
assert_eq!(res, (1, 2));
|
|
||||||
|
|
||||||
let lens = _0 + _1;
|
|
||||||
|
|
||||||
let res = lens(a);
|
|
||||||
assert_eq!(res, 2);
|
|
||||||
let res = lens(a, |v| v + 1);
|
|
||||||
assert_eq!(res, ((1, 3), 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
use crate::{Optics, OpticsTrait};
|
||||||
|
|
||||||
|
/// For lenses that allow viewing
|
||||||
|
pub trait PrismPreview<T>: OpticsTrait {
|
||||||
|
type Field;
|
||||||
|
|
||||||
|
fn preview(thing: T) -> Option<Self::Field>;
|
||||||
|
}
|
||||||
|
pub trait PrismReview<T>: PrismPreview<T> {
|
||||||
|
fn review(thing: Self::Field) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P, T> PrismPreview<T> for Optics<P>
|
||||||
|
where
|
||||||
|
P: PrismPreview<T>,
|
||||||
|
{
|
||||||
|
type Field = P::Field;
|
||||||
|
|
||||||
|
fn preview(thing: T) -> Option<Self::Field> {
|
||||||
|
P::preview(thing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P, T> PrismReview<T> for Optics<P>
|
||||||
|
where
|
||||||
|
P: PrismReview<T>,
|
||||||
|
{
|
||||||
|
fn review(thing: Self::Field) -> T {
|
||||||
|
P::review(thing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn preview<T, P: PrismPreview<T>>(_prism: P, thing: T) -> Option<P::Field> {
|
||||||
|
P::preview(thing)
|
||||||
|
}
|
||||||
|
pub fn review<T, P: PrismReview<T>>(_prism: P, thing: P::Field) -> T {
|
||||||
|
P::review(thing)
|
||||||
|
}
|
||||||
|
|
||||||
|
mod result;
|
||||||
|
pub use result::{_Err, _Ok};
|
||||||
|
|
||||||
|
mod option;
|
||||||
|
pub use option::{_None, _Some};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preview_result() {
|
||||||
|
let a: Result<i32, i32> = Ok(3);
|
||||||
|
assert_eq!(preview(_Ok, a), Some(3));
|
||||||
|
|
||||||
|
let a: Result<i32, i32> = Err(3);
|
||||||
|
assert_eq!(preview(_Ok, a), None);
|
||||||
|
|
||||||
|
let a: Result<i32, i32> = Ok(3);
|
||||||
|
assert_eq!(preview(_Err, a), None);
|
||||||
|
|
||||||
|
let a: Result<i32, i32> = Err(3);
|
||||||
|
assert_eq!(preview(_Err, a), Some(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preview_option() {
|
||||||
|
let a = Some(3);
|
||||||
|
assert_eq!(preview(_Some, a), Some(3));
|
||||||
|
|
||||||
|
let a = Some(3);
|
||||||
|
assert_eq!(preview(_None, a), Some(()));
|
||||||
|
|
||||||
|
let a: Option<i32> = None;
|
||||||
|
assert_eq!(preview(_Some, a), None);
|
||||||
|
|
||||||
|
let a: Option<i32> = None;
|
||||||
|
assert_eq!(preview(_None, a), Some(()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn review_result() {
|
||||||
|
assert_eq!(review(_Ok, 3), Ok::<i32, i32>(3));
|
||||||
|
assert_eq!(review(_Err, 3), Err::<i32, i32>(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn review_option() {
|
||||||
|
assert_eq!(review(_Some, 3), Some(3));
|
||||||
|
assert_eq!(review(_None, ()), None::<()>);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_combination() {}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct SomeInner;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const _Some: Optics<SomeInner> = Optics(SomeInner);
|
||||||
|
impl OpticsTrait for SomeInner {}
|
||||||
|
impl<T> PrismPreview<Option<T>> for SomeInner {
|
||||||
|
type Field = T;
|
||||||
|
|
||||||
|
fn preview(thing: Option<T>) -> Option<Self::Field> {
|
||||||
|
thing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PrismReview<Option<T>> for SomeInner {
|
||||||
|
fn review(thing: Self::Field) -> Option<T> {
|
||||||
|
Some(thing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct NoneInner;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const _None: Optics<NoneInner> = Optics(NoneInner);
|
||||||
|
impl OpticsTrait for NoneInner {}
|
||||||
|
impl<T> PrismPreview<Option<T>> for NoneInner {
|
||||||
|
type Field = ();
|
||||||
|
|
||||||
|
fn preview(_thing: Option<T>) -> Option<Self::Field> {
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PrismReview<Option<T>> for NoneInner {
|
||||||
|
fn review(_thing: Self::Field) -> Option<T> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct OkInner;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const _Ok: Optics<OkInner> = Optics(OkInner);
|
||||||
|
impl OpticsTrait for OkInner {}
|
||||||
|
impl<T, E> PrismPreview<Result<T, E>> for OkInner {
|
||||||
|
type Field = T;
|
||||||
|
|
||||||
|
fn preview(thing: Result<T, E>) -> Option<Self::Field> {
|
||||||
|
thing.ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> PrismReview<Result<T, E>> for OkInner {
|
||||||
|
fn review(thing: Self::Field) -> Result<T, E> {
|
||||||
|
Ok(thing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ErrInner;
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
pub const _Err: Optics<ErrInner> = Optics(ErrInner);
|
||||||
|
|
||||||
|
impl OpticsTrait for ErrInner {}
|
||||||
|
|
||||||
|
impl<T, E> PrismPreview<Result<T, E>> for ErrInner {
|
||||||
|
type Field = E;
|
||||||
|
|
||||||
|
fn preview(thing: Result<T, E>) -> Option<Self::Field> {
|
||||||
|
thing.err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> PrismReview<Result<T, E>> for ErrInner {
|
||||||
|
fn review(thing: Self::Field) -> Result<T, E> {
|
||||||
|
Err(thing)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue