Skip to content

Commit

Permalink
Implement Lens directly on a pair (#1654)
Browse files Browse the repository at this point in the history
* Implement Lens directly on a pair
* Implement Lens for tuples of length 3 to 7
* Update Changelog
  • Loading branch information
maan2003 authored Apr 14, 2021
1 parent 0c68463 commit ac3e0a6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 28 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ You can find its changes [documented below](#070---2021-01-01).
- `Notification`s can be submitted while handling other `Notification`s ([#1640] by [@cmyr])
- Added ListIter implementations for OrdMap ([#1641] by [@Lejero])
- `Padding` can now use `Key<Insets>` ([#1662] by [@cmyr])
- `LifeCycle::DisabledChanged`, `InternalLifeCycle::RouteDisabledChanged` and the `set_disabled()` and `is_disabled()`
- `LifeCycle::DisabledChanged`, `InternalLifeCycle::RouteDisabledChanged` and the `set_disabled()` and `is_disabled()`
context-methods to implement disabled ([#1632] by [@xarvic])
- `LifeCycle::BuildFocusChain` to update the focus-chain ([#1632] by [@xarvic])
- `DisabledIf` widget wrapper to disable based on the state of Data and Env ([#1702] by [@xarvic])
Expand All @@ -45,6 +45,7 @@ You can find its changes [documented below](#070---2021-01-01).
- Update to piet v0.4.0 (rich text on linux!) ([#1677] by [@cmyr])
- `register_for_focus()` should from now on be called from `LifeCycle::BuildFocusChain` instead of `LifeCycle::WidgetAdded` ([#1632] by [@xarvic])
- Flex values that are less than 0.0 will default to 0.0 and warn in release. It will panic in debug mode. ([#1691] by [@arthmis])
- Lens implemented for tuples of Lenses of length 2-8, Tuple2 removed ([#1654] by [@Maan2003])

### Deprecated

Expand Down Expand Up @@ -667,6 +668,7 @@ Last release without a changelog :(
[#1640]: https://github.com/linebender/druid/pull/1640
[#1641]: https://github.com/linebender/druid/pull/1641
[#1647]: https://github.com/linebender/druid/pull/1647
[#1654]: https://github.com/linebender/druid/pull/1654
[#1660]: https://github.com/linebender/druid/pull/1660
[#1662]: https://github.com/linebender/druid/pull/1662
[#1677]: https://github.com/linebender/druid/pull/1677
Expand Down
87 changes: 61 additions & 26 deletions druid/src/lens/lens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,30 +568,65 @@ impl<A, B: Clone> Lens<A, B> for Constant<B> {
}
}

/// A lens that combines two lenses into a tuple.
#[derive(Debug, Copy, Clone)]
pub struct Tuple2<L1, L2>(pub L1, pub L2);

impl<A, L1B, L2B, L1, L2> Lens<A, (L1B, L2B)> for Tuple2<L1, L2>
where
L1B: Clone,
L2B: Clone,
L1: Lens<A, L1B>,
L2: Lens<A, L2B>,
{
fn with<V, F: FnOnce(&(L1B, L2B)) -> V>(&self, data: &A, f: F) -> V {
let l1b = self.0.with(data, |v| v.clone());
let l2b = self.1.with(data, |v| v.clone());
f(&(l1b, l2b))
}
fn with_mut<V, F: FnOnce(&mut (L1B, L2B)) -> V>(&self, data: &mut A, f: F) -> V {
let l1b = self.0.with(data, |v| v.clone());
let l2b = self.1.with(data, |v| v.clone());
let mut tuple = (l1b, l2b);
let out = f(&mut tuple);
let (l1b, l2b) = tuple;
self.0.with_mut(data, |v| *v = l1b);
self.1.with_mut(data, |v| *v = l2b);
out
}
macro_rules! impl_lens_for_tuple {
($(($Lens:ident, $B:ident, $i:tt)),*) => {
#[allow(non_snake_case)]
impl<A, $($Lens,)* $($B,)*> Lens<A, ($($B,)*)> for ($($Lens,)*)
where
$($B: Clone,)*
$($Lens: Lens<A, $B>,)*
{
fn with<V, F: FnOnce(&($($B,)*)) -> V>(&self, data: &A, f: F) -> V {
$(let $B = self.$i.with(data, |v| v.clone());)*
let tuple = ($($B,)*);
f(&tuple)
}
fn with_mut<V, F: FnOnce(&mut ($($B,)*)) -> V>(&self, data: &mut A, f: F) -> V {
$(let $B = self.$i.with(data, |v| v.clone());)*
let mut tuple = ($($B,)*);
let out = f(&mut tuple);
let ($($B,)*) = tuple;
$(self.$i.with_mut(data, |v| *v = $B);)*
out
}
}
};
}

impl_lens_for_tuple!((L0, L0B, 0), (L1, L1B, 1));
impl_lens_for_tuple!((L0, L0B, 0), (L1, L1B, 1), (L2, L2B, 2));
impl_lens_for_tuple!((L0, L0B, 0), (L1, L1B, 1), (L2, L2B, 2), (L3, L3B, 3));
impl_lens_for_tuple!(
(L0, L0B, 0),
(L1, L1B, 1),
(L2, L2B, 2),
(L3, L3B, 3),
(L4, L4B, 4)
);
impl_lens_for_tuple!(
(L0, L0B, 0),
(L1, L1B, 1),
(L2, L2B, 2),
(L3, L3B, 3),
(L4, L4B, 4),
(L5, L5B, 5)
);
impl_lens_for_tuple!(
(L0, L0B, 0),
(L1, L1B, 1),
(L2, L2B, 2),
(L3, L3B, 3),
(L4, L4B, 4),
(L5, L5B, 5),
(L6, L6B, 6)
);
impl_lens_for_tuple!(
(L0, L0B, 0),
(L1, L1B, 1),
(L2, L2B, 2),
(L3, L3B, 3),
(L4, L4B, 4),
(L5, L5B, 5),
(L6, L6B, 6),
(L7, L7B, 7)
);
2 changes: 1 addition & 1 deletion druid/src/lens/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
#[allow(clippy::module_inception)]
#[macro_use]
mod lens;
pub use lens::{Constant, Deref, Field, Identity, InArc, Index, Map, Ref, Then, Tuple2, Unit};
pub use lens::{Constant, Deref, Field, Identity, InArc, Index, Map, Ref, Then, Unit};
#[doc(hidden)]
pub use lens::{Lens, LensExt};

0 comments on commit ac3e0a6

Please sign in to comment.