use std::sync::Arc; use crate::lenses::{Lens, LensOver, LensView}; type Getter = dyn Fn(T) -> U; type Setter = dyn Fn(T, U) -> T; #[derive(Clone)] pub struct FuncLens(pub(crate) Arc>, pub(crate) Arc>); impl LensView for FuncLens { type Field = U; fn view(&self, thing: T) -> Self::Field { (self.0)(thing) } } impl LensOver for FuncLens { fn over(&self, thing: T, f: F) -> T where F: FnOnce(Self::Field) -> Self::Field, { let v = f((self.0)(thing.clone())); (self.1)(thing, v) } fn set(&self, thing: T, v: Self::Field) -> T { (self.1)(thing, v) } } /// Makes a lens that implements `LensView` and `LensOver` with the provided functions pub fn lens_from_boxed( getter: Arc>, setter: Arc>, ) -> Lens> { Lens(FuncLens(getter, setter)) } /// Makes a lens that implements `LensView` and `LensOver` with the provided functions pub fn lens( getter: impl Fn(T) -> U + 'static, setter: impl Fn(T, U) -> T + 'static, ) -> Lens> { Lens(FuncLens(Arc::new(getter), Arc::new(setter))) }