diff options
author | Joe Wilm <joe@jwilm.com> | 2016-07-03 21:05:28 -0700 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-07-03 21:07:58 -0700 |
commit | 6639e6f24fab269f23392b11e566ef0a29ca163b (patch) | |
tree | 682a41a773d7b7f0b586a6459ad49ac45585007d /src/index.rs | |
parent | 63098f210e142453e14158a62c6fe0116d5fb94f (diff) | |
download | alacritty-6639e6f24fab269f23392b11e566ef0a29ca163b.tar.gz alacritty-6639e6f24fab269f23392b11e566ef0a29ca163b.zip |
Move ::grid::index to ::index
The grid and term modules already rely on the index types, and ansi is
about to be updated with strongly typed APIs. Since Cursor, Line, and
Column are fundamental to the code in several modules, namespacing them
under one of them seems less correct than a module that stands by
itself.
Diffstat (limited to 'src/index.rs')
-rw-r--r-- | src/index.rs | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/index.rs b/src/index.rs new file mode 100644 index 00000000..a4167e0d --- /dev/null +++ b/src/index.rs @@ -0,0 +1,241 @@ +// Copyright 2016 Joe Wilm, The Alacritty Project Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Line and Column newtypes for strongly typed tty/grid/terminal APIs + +/// Indexing types and implementations for Grid and Line +use std::fmt; +use std::iter::Step; +use std::num::{One, Zero}; +use std::ops::{self, Deref, Add}; + +/// Index in the grid using row, column notation +#[derive(Debug, Clone, Default, Eq, PartialEq)] +pub struct Cursor { + pub line: Line, + pub col: Column, +} + +/// A line +/// +/// Newtype to avoid passing values incorrectly +#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd)] +pub struct Line(pub usize); + +impl fmt::Display for Line { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Line({})", self.0) + } +} + +/// A column +/// +/// Newtype to avoid passing values incorrectly +#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd)] +pub struct Column(pub usize); + +impl fmt::Display for Column { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Column({})", self.0) + } +} + +/// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +/// file at the top-level directory of this distribution and at +/// http://rust-lang.org/COPYRIGHT. +/// +/// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +/// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +/// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +/// option. This file may not be copied, modified, or distributed +/// except according to those terms. +/// +/// implements binary operators "&T op U", "T op &U", "&T op &U" +/// based on "T op U" where T and U are expected to be `Copy`able +macro_rules! forward_ref_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + impl<'a> $imp<$u> for &'a $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, other) + } + } + + impl<'a> $imp<&'a $u> for $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(self, *other) + } + } + + impl<'a, 'b> $imp<&'a $u> for &'b $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, *other) + } + } + } +} + +/// Macro for deriving deref +macro_rules! deref { + ($ty:ty, $target:ty) => { + impl Deref for $ty { + type Target = $target; + + #[inline] + fn deref(&self) -> &$target { + &self.0 + } + } + } +} + +macro_rules! add { + ($ty:ty, $construct:expr) => { + impl ops::Add<$ty> for $ty { + type Output = $ty; + + #[inline] + fn add(self, rhs: $ty) -> $ty { + $construct(self.0 + rhs.0) + } + } + } +} + +macro_rules! sub { + ($ty:ty, $construct:expr) => { + impl ops::Sub<$ty> for $ty { + type Output = $ty; + + #[inline] + fn sub(self, rhs: $ty) -> $ty { + $construct(self.0 - rhs.0) + } + } + } +} + +macro_rules! zero_one { + ($ty:ty, $construct:expr) => { + impl One for $ty { + fn one() -> $ty { + $construct(1) + } + } + + impl Zero for $ty { + fn zero() -> $ty { + $construct(0) + } + } + } +} + +macro_rules! ops { + ($ty:ty, $construct:expr) => { + add!($ty, $construct); + sub!($ty, $construct); + zero_one!($ty, $construct); + deref!($ty, usize); + forward_ref_binop!(impl Add, add for $ty, $ty); + + impl Step for $ty { + fn step(&self, by: &$ty) -> Option<$ty> { + Some(*self + *by) + } + + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$ty, end: &$ty, by: &$ty) -> Option<usize> { + if *by == $construct(0) { return None; } + if *start < *end { + // Note: We assume $t <= usize here + let diff = (*end - *start).0; + let by = by.0; + if diff % by > 0 { + Some(diff / by + 1) + } else { + Some(diff / by) + } + } else { + Some(0) + } + } + } + + impl ops::AddAssign<$ty> for $ty { + #[inline] + fn add_assign(&mut self, rhs: $ty) { + self.0 += rhs.0 + } + } + + impl ops::SubAssign<$ty> for $ty { + #[inline] + fn sub_assign(&mut self, rhs: $ty) { + self.0 -= rhs.0 + } + } + + impl ops::AddAssign<usize> for $ty { + #[inline] + fn add_assign(&mut self, rhs: usize) { + self.0 += rhs + } + } + + impl ops::SubAssign<usize> for $ty { + #[inline] + fn sub_assign(&mut self, rhs: usize) { + self.0 -= rhs + } + } + + impl From<usize> for $ty { + #[inline] + fn from(val: usize) -> $ty { + $construct(val) + } + } + + impl ops::Add<usize> for $ty { + type Output = $ty; + + #[inline] + fn add(self, rhs: usize) -> $ty { + $construct(self.0 + rhs) + } + } + + impl ops::Sub<usize> for $ty { + type Output = $ty; + + #[inline] + fn sub(self, rhs: usize) -> $ty { + $construct(self.0 - rhs) + } + } + } +} + +ops!(Line, Line); +ops!(Column, Column); |