Add Vec2::saturating_add(XY<isize>)

And uses it to fix crash in position example
This commit is contained in:
Alexandre Bury 2018-02-07 16:44:22 -08:00
parent 9e591ef635
commit daac2d67b4
2 changed files with 34 additions and 20 deletions

View File

@ -11,23 +11,12 @@ fn move_top(c: &mut Cursive, x_in: isize, y_in: isize) {
let s = c.screen_mut(); let s = c.screen_mut();
let l = LayerPosition::FromFront(0); let l = LayerPosition::FromFront(0);
let (x, y) = s.offset().pair();
// Step 2. add the specifed amount // Step 2. add the specifed amount
// (unsigned math in Rust is a mess.) let pos = s.offset().saturating_add((x_in, y_in));
let x = if x_in < 0 {
x - (-x_in) as usize
} else {
x + x_in as usize
};
let y = if y_in < 0 {
y - (-y_in) as usize
} else {
y + y_in as usize
};
// convert the new x and y into a position // convert the new x and y into a position
let p = Position::absolute((x, y)); let p = Position::absolute(pos);
// Step 3. Apply the new position // Step 3. Apply the new position
s.reposition_layer(l, p); s.reposition_layer(l, p);

View File

@ -35,10 +35,22 @@ impl XY<usize> {
/// Never panics. /// Never panics.
pub fn saturating_sub<O: Into<Self>>(&self, other: O) -> Self { pub fn saturating_sub<O: Into<Self>>(&self, other: O) -> Self {
let other = other.into(); let other = other.into();
Self::new( self.zip_map(other, usize::saturating_sub)
self.x.saturating_sub(other.x), }
self.y.saturating_sub(other.y),
) /// Saturating addition with a signed vec.
///
/// Any coordinates saturates to 0.
pub fn saturating_add<O: Into<XY<isize>>>(&self, other: O) -> Self {
let other = other.into();
self.zip_map(other, |s, o| {
if o > 0 {
s + o as usize
} else {
s.saturating_sub((-o) as usize)
}
})
} }
/// Checked subtraction. Computes `self - other` if possible. /// Checked subtraction. Computes `self - other` if possible.
@ -152,7 +164,11 @@ impl<T: Zero + Clone> XY<T> {
} }
} }
impl<T: Into<XY<usize>>> From<T> for XY<isize> { // Anything that can become XY<usize> can also become XY<isize>
impl<T> From<T> for XY<isize>
where
T: Into<XY<usize>>,
{
fn from(t: T) -> Self { fn from(t: T) -> Self {
let other = t.into(); let other = t.into();
Self::new(other.x as isize, other.y as isize) Self::new(other.x as isize, other.y as isize)
@ -183,7 +199,12 @@ impl From<(u16, u16)> for XY<usize> {
} }
} }
impl<T: Add<Output = T>, O: Into<XY<T>>> Add<O> for XY<T> { // Allow xy + (into xy)
impl<T, O> Add<O> for XY<T>
where
T: Add<Output = T>,
O: Into<XY<T>>,
{
type Output = Self; type Output = Self;
fn add(self, other: O) -> Self { fn add(self, other: O) -> Self {
@ -191,7 +212,11 @@ impl<T: Add<Output = T>, O: Into<XY<T>>> Add<O> for XY<T> {
} }
} }
impl<T: Sub<Output = T>, O: Into<XY<T>>> Sub<O> for XY<T> { impl<T, O> Sub<O> for XY<T>
where
T: Sub<Output = T>,
O: Into<XY<T>>,
{
type Output = Self; type Output = Self;
fn sub(self, other: O) -> Self { fn sub(self, other: O) -> Self {