replace Box with Arc so lenses are clonable

main
annieversary 2021-11-15 22:21:17 +00:00
parent 2bf792d0f5
commit 4a1f398fe3
2 changed files with 14 additions and 8 deletions

View File

@ -1,9 +1,12 @@
use std::sync::Arc;
use crate::lenses::{Lens, LensOver, LensView}; use crate::lenses::{Lens, LensOver, LensView};
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 FuncLens<T, U>(pub(crate) Box<Getter<T, U>>, pub(crate) Box<Setter<T, U>>); #[derive(Clone)]
pub struct FuncLens<T, U>(pub(crate) Arc<Getter<T, U>>, pub(crate) Arc<Setter<T, U>>);
impl<T, U> LensView<T> for FuncLens<T, U> { impl<T, U> LensView<T> for FuncLens<T, U> {
type Field = U; type Field = U;
@ -28,8 +31,8 @@ impl<T: Clone, U> LensOver<T> for FuncLens<T, U> {
/// 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_from_boxed<T, U>( pub fn lens_from_boxed<T, U>(
getter: Box<Getter<T, U>>, getter: Arc<Getter<T, U>>,
setter: Box<Setter<T, U>>, setter: Arc<Setter<T, U>>,
) -> Lens<FuncLens<T, U>> { ) -> Lens<FuncLens<T, U>> {
Lens(FuncLens(getter, setter)) Lens(FuncLens(getter, setter))
} }
@ -38,5 +41,5 @@ 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,
) -> Lens<FuncLens<T, U>> { ) -> Lens<FuncLens<T, U>> {
Lens(FuncLens(Box::new(getter), Box::new(setter))) Lens(FuncLens(Arc::new(getter), Arc::new(setter)))
} }

View File

@ -1,8 +1,11 @@
use std::sync::Arc;
use crate::lenses::{Lens, LensView}; use crate::lenses::{Lens, LensView};
use super::lens::FuncLens; use super::lens::FuncLens;
pub struct ToInner<T, U>(Box<dyn Fn(T) -> U>); #[derive(Clone)]
pub struct ToInner<T, U>(Arc<dyn Fn(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;
@ -13,17 +16,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>) -> Lens<ToInner<T, U>> { pub fn to_from_boxed<T, U>(f: Arc<dyn Fn(T) -> U>) -> Lens<ToInner<T, U>> {
Lens(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) -> Lens<ToInner<T, U>> { pub fn to<T, U>(f: impl Fn(T) -> U + 'static) -> Lens<ToInner<T, U>> {
Lens(ToInner(Box::new(f))) Lens(ToInner(Arc::new(f)))
} }
impl<T, U> Lens<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) -> Lens<FuncLens<T, U>> { pub fn make_lens(self, setter: impl Fn(T, U) -> T + 'static) -> Lens<FuncLens<T, U>> {
Lens(FuncLens((self.0).0, Box::new(setter))) Lens(FuncLens((self.0).0, Arc::new(setter)))
} }
} }