|
| 1 | +#![feature(step_trait)] |
| 2 | + |
1 | 3 | #[cfg(feature = "derive")]
|
2 | 4 | #[macro_use]
|
3 | 5 | extern crate serde_derive;
|
4 | 6 |
|
5 | 7 | use serde::{Deserialize, Serialize};
|
6 | 8 |
|
| 9 | +use std::convert::TryFrom; |
| 10 | +use std::iter::Step; |
7 | 11 | use std::marker::PhantomData;
|
8 | 12 | use std::path::PathBuf;
|
9 | 13 |
|
@@ -78,6 +82,62 @@ impl Column<ZeroIndexed> {
|
78 | 82 | }
|
79 | 83 | }
|
80 | 84 |
|
| 85 | +impl Step for Column<ZeroIndexed> { |
| 86 | + fn steps_between(start: &Self, end: &Self) -> Option<usize> { |
| 87 | + <u32 as Step>::steps_between(&start.0, &end.0) |
| 88 | + } |
| 89 | + |
| 90 | + fn replace_one(&mut self) -> Self { |
| 91 | + self.0 = 1; |
| 92 | + self.clone() |
| 93 | + } |
| 94 | + |
| 95 | + fn replace_zero(&mut self) -> Self { |
| 96 | + self.0 = 0; |
| 97 | + self.clone() |
| 98 | + } |
| 99 | + |
| 100 | + fn add_one(&self) -> Self { |
| 101 | + Self::new(self.0 + 1) |
| 102 | + } |
| 103 | + |
| 104 | + fn sub_one(&self) -> Self { |
| 105 | + Self::new(self.0 - 1) |
| 106 | + } |
| 107 | + |
| 108 | + fn add_usize(&self, n: usize) -> Option<Self> { |
| 109 | + (self.0 as usize).checked_add(n).and_then(|n| u32::try_from(n).ok()).map(Self::new) |
| 110 | + } |
| 111 | +} |
| 112 | + |
| 113 | +impl Step for Column<OneIndexed> { |
| 114 | + fn steps_between(start: &Self, end: &Self) -> Option<usize> { |
| 115 | + Some((end.0 - start.0) as usize) |
| 116 | + } |
| 117 | + |
| 118 | + fn replace_one(&mut self) -> Self { |
| 119 | + self.0 = 2; |
| 120 | + self.clone() |
| 121 | + } |
| 122 | + |
| 123 | + fn replace_zero(&mut self) -> Self { |
| 124 | + self.0 = 1; |
| 125 | + self.clone() |
| 126 | + } |
| 127 | + |
| 128 | + fn add_one(&self) -> Self { |
| 129 | + Self::new(self.0 + 1) |
| 130 | + } |
| 131 | + |
| 132 | + fn sub_one(&self) -> Self { |
| 133 | + Self::new(self.0 - 1) |
| 134 | + } |
| 135 | + |
| 136 | + fn add_usize(&self, n: usize) -> Option<Self> { |
| 137 | + (self.0 as usize).checked_add(n).and_then(|n| u32::try_from(n).ok()).map(Self::new) |
| 138 | + } |
| 139 | +} |
| 140 | + |
81 | 141 | #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
82 | 142 | pub struct Row<I: Indexed>(pub u32, PhantomData<I>);
|
83 | 143 |
|
@@ -141,6 +201,62 @@ impl Row<ZeroIndexed> {
|
141 | 201 | }
|
142 | 202 | }
|
143 | 203 |
|
| 204 | +impl Step for Row<ZeroIndexed> { |
| 205 | + fn steps_between(start: &Self, end: &Self) -> Option<usize> { |
| 206 | + Some((end.0 - start.0) as usize) |
| 207 | + } |
| 208 | + |
| 209 | + fn replace_one(&mut self) -> Self { |
| 210 | + self.0 = 1; |
| 211 | + self.clone() |
| 212 | + } |
| 213 | + |
| 214 | + fn replace_zero(&mut self) -> Self { |
| 215 | + self.0 = 0; |
| 216 | + self.clone() |
| 217 | + } |
| 218 | + |
| 219 | + fn add_one(&self) -> Self { |
| 220 | + Self::new(self.0 + 1) |
| 221 | + } |
| 222 | + |
| 223 | + fn sub_one(&self) -> Self { |
| 224 | + Self::new(self.0 - 1) |
| 225 | + } |
| 226 | + |
| 227 | + fn add_usize(&self, n: usize) -> Option<Self> { |
| 228 | + (self.0 as usize).checked_add(n).and_then(|n| u32::try_from(n).ok()).map(Self::new) |
| 229 | + } |
| 230 | +} |
| 231 | + |
| 232 | +impl Step for Row<OneIndexed> { |
| 233 | + fn steps_between(start: &Self, end: &Self) -> Option<usize> { |
| 234 | + Some((end.0 - start.0) as usize) |
| 235 | + } |
| 236 | + |
| 237 | + fn replace_one(&mut self) -> Self { |
| 238 | + self.0 = 2; |
| 239 | + self.clone() |
| 240 | + } |
| 241 | + |
| 242 | + fn replace_zero(&mut self) -> Self { |
| 243 | + self.0 = 1; |
| 244 | + self.clone() |
| 245 | + } |
| 246 | + |
| 247 | + fn add_one(&self) -> Self { |
| 248 | + Self::new(self.0 + 1) |
| 249 | + } |
| 250 | + |
| 251 | + fn sub_one(&self) -> Self { |
| 252 | + Self::new(self.0 - 1) |
| 253 | + } |
| 254 | + |
| 255 | + fn add_usize(&self, n: usize) -> Option<Self> { |
| 256 | + (self.0 as usize).checked_add(n).and_then(|n| u32::try_from(n).ok()).map(Self::new) |
| 257 | + } |
| 258 | +} |
| 259 | + |
144 | 260 | #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))]
|
145 | 261 | #[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable, RustcEncodable))]
|
146 | 262 | #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
@@ -339,4 +455,18 @@ pub struct OneIndexed;
|
339 | 455 | impl Indexed for OneIndexed {}
|
340 | 456 |
|
341 | 457 | #[cfg(test)]
|
342 |
| -mod test {} |
| 458 | +mod test { |
| 459 | + use super::*; |
| 460 | + |
| 461 | + #[test] |
| 462 | + fn iter_row() { |
| 463 | + assert_eq!((Row::new_one_indexed(4)..Row::new_one_indexed(8)).count(), 4); |
| 464 | + assert_eq!( |
| 465 | + &*(Row::new_zero_indexed(0)..=Row::new_zero_indexed(8)) |
| 466 | + .filter(|r| r.0 < 3) |
| 467 | + .map(|r| r.0) |
| 468 | + .collect::<Vec<_>>(), |
| 469 | + &[0, 1, 2], |
| 470 | + ); |
| 471 | + } |
| 472 | +} |
0 commit comments