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};
type Getter<T, U> = dyn Fn(T) -> U;
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> {
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
pub fn lens_from_boxed<T, U>(
getter: Box<Getter<T, U>>,
setter: Box<Setter<T, U>>,
getter: Arc<Getter<T, U>>,
setter: Arc<Setter<T, U>>,
) -> Lens<FuncLens<T, U>> {
Lens(FuncLens(getter, setter))
}
@ -38,5 +41,5 @@ pub fn lens<T, U>(
getter: impl Fn(T) -> U + 'static,
setter: impl Fn(T, U) -> T + 'static,
) -> 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 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> {
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
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))
}
/// 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>> {
Lens(ToInner(Box::new(f)))
Lens(ToInner(Arc::new(f)))
}
impl<T, U> Lens<ToInner<T, U>> {
/// 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>> {
Lens(FuncLens((self.0).0, Box::new(setter)))
Lens(FuncLens((self.0).0, Arc::new(setter)))
}
}