@@ -47,12 +47,24 @@ impl LineRange {
4747 }
4848 2 => {
4949 new_range.lower = line_numbers[0].parse()?;
50+ let first_byte = line_numbers[1].bytes().next();
5051
51− new_range.upper = if line_numbers[1].bytes().next() == Some(b'+') {
52+ new_range.upper = if first_byte == Some(b'+') {
5253 let more_lines = &line_numbers[1][1..]
5354 .parse()
5455 .map_err(|_| "Invalid character after +")?;
5556 new_range.lower + more_lines
57+ } else if first_byte == Some(b'-') {
58+ // this will prevent values like "-+5" even though "+5" is valid integer
59+ if &line_numbers[1][1..].bytes().next() == &Some(b'+') {
60+ return Err("Invalid character after -".into());
61+ }
62+ let less_lines = &line_numbers[1][1..]
63+ .parse()
64+ .map_err(|_| "Invalid character after -")?;
65+ let prev_lower = new_range.lower;
66+ new_range.lower = new_range.lower - less_lines;
67+ prev_lower
5668 } else {
5769 line_numbers[1].parse()?
5870 };
@@ -126,6 +138,23 @@ fn test_parse_plus_fail() {
126138 assert!(range.is_err());
127139}
128140
141+#[test]
142+fn test_parse_minus_success() {
143+ let range = LineRange::from("40:-10").expect("Shouldn't fail on test!");
144+ assert_eq!(30, range.lower);
145+ assert_eq!(40, range.upper);
146+}
147+
148+#[test]
149+fn test_parse_minus_fail() {
150+ let range = LineRange::from("40:-z");
151+ assert!(range.is_err());
152+ let range = LineRange::from("40:-+10");
153+ assert!(range.is_err());
154+ let range = LineRange::from("40:-");
155+ assert!(range.is_err());
156+}
157+
129158#[derive(Copy, Clone, Debug, PartialEq)]
130159pub enum RangeCheckResult {
131160 // Within one of the given ranges