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