mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add some more XY methods
This commit is contained in:
parent
39babacbf5
commit
56ce95f9b6
65
src/xy.rs
65
src/xy.rs
@ -16,18 +16,45 @@ impl<T> XY<T> {
|
||||
XY { x: x, y: y }
|
||||
}
|
||||
|
||||
/// Returns `f(self.x, self.y)`
|
||||
pub fn fold<U, F>(self, f: F) -> U
|
||||
where
|
||||
F: FnOnce(T, T) -> U,
|
||||
{
|
||||
f(self.x, self.y)
|
||||
}
|
||||
|
||||
/// Creates a new `XY` by applying `f` to `x` and `y`.
|
||||
pub fn map<U, F: Fn(T) -> U>(self, f: F) -> XY<U> {
|
||||
pub fn map<U, F>(self, f: F) -> XY<U>
|
||||
where
|
||||
F: Fn(T) -> U,
|
||||
{
|
||||
XY::new(f(self.x), f(self.y))
|
||||
}
|
||||
|
||||
/// Applies `f` on axis where `condition` is true.
|
||||
///
|
||||
/// Carries over `self` otherwise.
|
||||
pub fn map_if<F>(self, condition: XY<bool>, f: F) -> Self
|
||||
where
|
||||
F: Fn(T) -> T,
|
||||
{
|
||||
self.zip_map(condition, |v, c| if c { f(v) } else { v })
|
||||
}
|
||||
|
||||
/// Creates a new `XY` by applying `f` to `x`, and carrying `y` over.
|
||||
pub fn map_x<F: Fn(T) -> T>(self, f: F) -> Self {
|
||||
pub fn map_x<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
XY::new(f(self.x), self.y)
|
||||
}
|
||||
|
||||
/// Creates a new `XY` by applying `f` to `y`, and carrying `x` over.
|
||||
pub fn map_y<F: Fn(T) -> T>(self, f: F) -> Self {
|
||||
pub fn map_y<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
XY::new(self.x, f(self.y))
|
||||
}
|
||||
|
||||
@ -68,7 +95,10 @@ impl<T> XY<T> {
|
||||
}
|
||||
|
||||
/// Returns a new `XY` by calling `f` on `self` and `other` for each axis.
|
||||
pub fn zip_map<U, V, F: Fn(T, U) -> V>(self, other: XY<U>, f: F) -> XY<V> {
|
||||
pub fn zip_map<U, V, F>(self, other: XY<U>, f: F) -> XY<V>
|
||||
where
|
||||
F: Fn(T, U) -> V,
|
||||
{
|
||||
XY::new(f(self.x, other.x), f(self.y, other.y))
|
||||
}
|
||||
}
|
||||
@ -97,19 +127,34 @@ impl<T: Clone> XY<T> {
|
||||
impl<T> XY<Option<T>> {
|
||||
/// Returns a new `XY` by calling `unwrap_or` on each axis.
|
||||
pub fn unwrap_or(self, other: XY<T>) -> XY<T> {
|
||||
self.zip_map(other, |s, o| s.unwrap_or(o))
|
||||
self.zip_map(other, Option::unwrap_or)
|
||||
}
|
||||
}
|
||||
|
||||
impl XY<bool> {
|
||||
/// Returns `true` if any of `x` or `y` is `true`.
|
||||
pub fn any(&self) -> bool {
|
||||
self.x || self.y
|
||||
use std::ops::BitOr;
|
||||
self.fold(BitOr::bitor)
|
||||
}
|
||||
|
||||
/// Returns `true` if both `x` and `y` are `true`.
|
||||
pub fn both(&self) -> bool {
|
||||
self.x && self.y
|
||||
use std::ops::BitAnd;
|
||||
self.fold(BitAnd::bitand)
|
||||
}
|
||||
|
||||
/// For each axis, keeps elements from `other` if `self` is `true`.
|
||||
pub fn select<T>(&self, other: XY<T>) -> XY<Option<T>> {
|
||||
self.zip_map(
|
||||
other,
|
||||
|keep, o| if keep { Some(o) } else { None },
|
||||
)
|
||||
}
|
||||
|
||||
/// For each axis, selects `if_true` if `self` is true, else `if_false`.
|
||||
pub fn select_or<T>(&self, if_true: XY<T>, if_false: XY<T>) -> XY<T> {
|
||||
self.select(if_true).unwrap_or(if_false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,3 +170,9 @@ impl<T> From<(T, T)> for XY<T> {
|
||||
XY::new(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> From<(XY<T>, XY<U>)> for XY<(T, U)> {
|
||||
fn from((t, u): (XY<T>, XY<U>)) -> Self {
|
||||
t.zip(u)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user