rename lens to optics
parent
30996082ac
commit
037440c845
|
@ -1,7 +1,4 @@
|
|||
use bad_optics::{
|
||||
lenses::{_0, _1},
|
||||
*,
|
||||
};
|
||||
use bad_optics::lenses::*;
|
||||
|
||||
fn main() {
|
||||
let a = ((1, 2), 3);
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
use crate::{Lens, LensOver, LensTrait, LensView};
|
||||
use crate::{
|
||||
lenses::{LensOver, LensView},
|
||||
Optics, OpticsTrait,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Combination<A, B>(A, B);
|
||||
impl<A, B> LensTrait for Combination<A, B> {}
|
||||
impl<A, B> OpticsTrait for Combination<A, B> {}
|
||||
|
||||
impl<A, B> std::ops::Add<Lens<B>> for Lens<A>
|
||||
impl<A, B> std::ops::Add<Optics<B>> for Optics<A>
|
||||
where
|
||||
A: LensTrait,
|
||||
B: LensTrait,
|
||||
A: OpticsTrait,
|
||||
B: OpticsTrait,
|
||||
{
|
||||
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
|
||||
type Output = Optics<Combination<Optics<A>, Optics<B>>>;
|
||||
|
||||
fn add(self, rhs: Lens<B>) -> Self::Output {
|
||||
Lens(Combination(self, rhs))
|
||||
fn add(self, rhs: Optics<B>) -> Self::Output {
|
||||
Optics(Combination(self, rhs))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
src/fns.rs
17
src/fns.rs
|
@ -1,6 +1,9 @@
|
|||
use crate::{Lens, LensOver, LensView};
|
||||
use crate::{
|
||||
lenses::{LensOver, LensView},
|
||||
Optics,
|
||||
};
|
||||
|
||||
impl<L, A> std::ops::FnOnce<(A,)> for Lens<L>
|
||||
impl<L, A> std::ops::FnOnce<(A,)> for Optics<L>
|
||||
where
|
||||
L: LensView<A>,
|
||||
{
|
||||
|
@ -10,7 +13,7 @@ where
|
|||
L::view(args.0)
|
||||
}
|
||||
}
|
||||
impl<L, A> std::ops::FnMut<(A,)> for Lens<L>
|
||||
impl<L, A> std::ops::FnMut<(A,)> for Optics<L>
|
||||
where
|
||||
L: LensView<A>,
|
||||
{
|
||||
|
@ -18,7 +21,7 @@ where
|
|||
L::view(args.0)
|
||||
}
|
||||
}
|
||||
impl<L, A> std::ops::Fn<(A,)> for Lens<L>
|
||||
impl<L, A> std::ops::Fn<(A,)> for Optics<L>
|
||||
where
|
||||
L: LensView<A>,
|
||||
{
|
||||
|
@ -27,7 +30,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<L, A, F> std::ops::FnOnce<(A, F)> for Lens<L>
|
||||
impl<L, A, F> std::ops::FnOnce<(A, F)> for Optics<L>
|
||||
where
|
||||
L: LensOver<A>,
|
||||
F: FnOnce(L::Field) -> L::Field,
|
||||
|
@ -38,7 +41,7 @@ where
|
|||
L::over(args.0, args.1)
|
||||
}
|
||||
}
|
||||
impl<L, A, F> std::ops::FnMut<(A, F)> for Lens<L>
|
||||
impl<L, A, F> std::ops::FnMut<(A, F)> for Optics<L>
|
||||
where
|
||||
L: LensOver<A>,
|
||||
F: FnOnce(L::Field) -> L::Field,
|
||||
|
@ -47,7 +50,7 @@ where
|
|||
L::over(args.0, args.1)
|
||||
}
|
||||
}
|
||||
impl<L, A, F> std::ops::Fn<(A, F)> for Lens<L>
|
||||
impl<L, A, F> std::ops::Fn<(A, F)> for Optics<L>
|
||||
where
|
||||
L: LensOver<A>,
|
||||
F: FnOnce(L::Field) -> L::Field,
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use crate::{Lens, LensOver, LensTrait, LensView};
|
||||
use crate::{
|
||||
lenses::{LensOver, LensView},
|
||||
Optics, OpticsTrait,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct _0Inner;
|
||||
pub const _0: Lens<_0Inner> = Lens(_0Inner);
|
||||
impl LensTrait for _0Inner {}
|
||||
pub const _0: Optics<_0Inner> = Optics(_0Inner);
|
||||
impl OpticsTrait for _0Inner {}
|
||||
|
||||
macro_rules! make_tuples {
|
||||
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use crate::{LensOver, LensTrait, LensView};
|
||||
use crate::{
|
||||
lenses::{LensOver, LensView},
|
||||
OpticsTrait,
|
||||
};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct id;
|
||||
|
||||
impl LensTrait for id {}
|
||||
impl OpticsTrait for id {}
|
||||
impl<T> LensView<T> for id {
|
||||
type Field = T;
|
||||
|
||||
|
|
|
@ -5,3 +5,55 @@ mod first;
|
|||
pub use first::_0;
|
||||
mod second;
|
||||
pub use second::_1;
|
||||
|
||||
use crate::{Optics, OpticsTrait};
|
||||
|
||||
/// For lenses that allow viewing
|
||||
pub trait LensView<T>: OpticsTrait {
|
||||
type Field;
|
||||
|
||||
fn view(thing: T) -> Self::Field;
|
||||
}
|
||||
|
||||
/// For lenses that allow setting
|
||||
pub trait LensOver<T>: LensView<T> {
|
||||
fn over<F>(thing: T, f: F) -> T
|
||||
where
|
||||
F: FnOnce(Self::Field) -> Self::Field;
|
||||
|
||||
fn set(thing: T, v: Self::Field) -> T {
|
||||
Self::over(thing, |_| v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, T> LensView<T> for Optics<L>
|
||||
where
|
||||
L: LensView<T>,
|
||||
{
|
||||
type Field = L::Field;
|
||||
|
||||
fn view(thing: T) -> Self::Field {
|
||||
L::view(thing)
|
||||
}
|
||||
}
|
||||
impl<L, T> LensOver<T> for Optics<L>
|
||||
where
|
||||
L: LensOver<T>,
|
||||
{
|
||||
fn over<F>(thing: T, f: F) -> T
|
||||
where
|
||||
F: FnOnce(Self::Field) -> Self::Field,
|
||||
{
|
||||
L::over(thing, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
|
||||
L::view(thing)
|
||||
}
|
||||
pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
|
||||
L::set(thing, v)
|
||||
}
|
||||
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
|
||||
L::over(thing, f)
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
use crate::{Lens, LensOver, LensTrait, LensView};
|
||||
use crate::{
|
||||
lenses::{LensOver, LensView},
|
||||
Optics, OpticsTrait,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct _1Inner;
|
||||
pub const _1: Lens<_1Inner> = Lens(_1Inner);
|
||||
impl LensTrait for _1Inner {}
|
||||
pub const _1: Optics<_1Inner> = Optics(_1Inner);
|
||||
impl OpticsTrait for _1Inner {}
|
||||
|
||||
macro_rules! make_tuples {
|
||||
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||
|
|
73
src/lib.rs
73
src/lib.rs
|
@ -1,81 +1,30 @@
|
|||
#![feature(unboxed_closures, fn_traits)]
|
||||
|
||||
/// Base trait
|
||||
pub trait LensTrait {}
|
||||
|
||||
/// For lenses that allow viewing
|
||||
pub trait LensView<T>: LensTrait {
|
||||
type Field;
|
||||
|
||||
fn view(thing: T) -> Self::Field;
|
||||
}
|
||||
|
||||
/// For lenses that allow setting
|
||||
pub trait LensOver<T>: LensView<T> {
|
||||
fn over<F>(thing: T, f: F) -> T
|
||||
where
|
||||
F: FnOnce(Self::Field) -> Self::Field;
|
||||
|
||||
fn set(thing: T, v: Self::Field) -> T {
|
||||
Self::over(thing, |_| v)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper type
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Lens<T: LensTrait>(T);
|
||||
|
||||
impl<L: LensTrait> LensTrait for Lens<L> {}
|
||||
impl<L, T> LensView<T> for Lens<L>
|
||||
where
|
||||
L: LensView<T>,
|
||||
{
|
||||
type Field = L::Field;
|
||||
|
||||
fn view(thing: T) -> Self::Field {
|
||||
L::view(thing)
|
||||
}
|
||||
}
|
||||
impl<L, T> LensOver<T> for Lens<L>
|
||||
where
|
||||
L: LensOver<T>,
|
||||
{
|
||||
fn over<F>(thing: T, f: F) -> T
|
||||
where
|
||||
F: FnOnce(Self::Field) -> Self::Field,
|
||||
{
|
||||
L::over(thing, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
|
||||
L::view(thing)
|
||||
}
|
||||
pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
|
||||
L::set(thing, v)
|
||||
}
|
||||
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: impl FnOnce(L::Field) -> L::Field) -> T {
|
||||
L::over(thing, f)
|
||||
}
|
||||
|
||||
// TODO add third_from_tuple, etc
|
||||
|
||||
// TODO array traversals
|
||||
|
||||
// TODO something for structs
|
||||
|
||||
// TODO something for Ok, Some, etc
|
||||
|
||||
// TODO make over work with changing types
|
||||
|
||||
/// Base trait
|
||||
pub trait OpticsTrait {}
|
||||
|
||||
/// Wrapper type
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Optics<T: OpticsTrait>(pub(crate) T);
|
||||
impl<L: OpticsTrait> OpticsTrait for Optics<L> {}
|
||||
|
||||
mod combinations;
|
||||
mod fns;
|
||||
pub mod lenses;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
lenses::{_0, _1},
|
||||
*,
|
||||
};
|
||||
use super::lenses::*;
|
||||
|
||||
#[test]
|
||||
fn view_first_from_tuple() {
|
||||
|
|
Loading…
Reference in New Issue