1use crate::{Error, Index, Row};
2use std::str::FromStr;
3
4impl FromStr for Row {
7 type Err = Error;
8
9 fn from_str(s: &str) -> Result<Self, Self::Err> {
10 let mut absolute = false;
11
12 let ys = if let Some(without_abs) = s.strip_prefix('$') {
13 absolute = true;
14 without_abs
15 } else {
16 s
17 };
18
19 let y = ys.parse::<Index>().map_err(|e| {
20 Error::parse_error(
21 s,
22 format!("Error parsing number part of A1 reference: {e:?}"),
23 )
24 })?;
25
26 if y < 1 {
27 return Err(Error::parse_error(
28 y.to_string(),
29 "A1 reference must be greater than 0",
30 ));
31 }
32
33 Ok(Self { absolute, y: y - 1 })
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use crate::*;
40
41 #[test]
42 fn from_str_ok() {
43 assert_eq!(Row::from_str("1").unwrap(), Row::new(0));
44 assert_eq!(Row::from_str("124").unwrap(), Row::new(123));
45 }
46
47 #[test]
48 fn from_str_ok_absolute() {
49 assert_eq!(
50 Row::from_str("$1").unwrap(),
51 Row {
52 y: 0,
53 absolute: true
54 }
55 );
56 assert_eq!(
57 Row::from_str("$124").unwrap(),
58 Row {
59 y: 123,
60 absolute: true
61 }
62 );
63 }
64
65 #[test]
66 fn from_str_error() {
67 assert!(Row::from_str("ABC").is_err());
68 assert!(Row::from_str(" ! < ").is_err());
69 }
70}