1use crate::RangeOrCell;
18use std::str;
19
20mod display;
21mod from_str;
22mod into_iterator;
23mod iterator;
24
25#[cfg_attr(
26 feature = "rkyv",
27 derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)
28)]
29#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
30#[derive(Clone, Debug, PartialEq)]
31pub struct A1 {
32 pub sheet_name: Option<String>,
33 pub reference: RangeOrCell,
34}
35
36impl A1 {
37 pub fn contains(&self, other: &Self) -> bool {
40 self.sheet_name == other.sheet_name && self.reference.contains(&other.reference)
41 }
42
43 pub fn shift_down(self, rows: usize) -> Self {
45 Self {
46 reference: self.reference.shift_down(rows),
47 ..self
48 }
49 }
50
51 pub fn shift_left(self, columns: usize) -> Self {
53 Self {
54 reference: self.reference.shift_left(columns),
55 ..self
56 }
57 }
58
59 pub fn shift_right(self, columns: usize) -> Self {
61 Self {
62 reference: self.reference.shift_right(columns),
63 ..self
64 }
65 }
66
67 pub fn shift_up(self, rows: usize) -> Self {
69 Self {
70 reference: self.reference.shift_up(rows),
71 ..self
72 }
73 }
74
75 pub fn with_sheet_name(self, sheet_name: &str) -> Self {
77 Self {
78 sheet_name: Some(sheet_name.to_owned()),
79 ..self
80 }
81 }
82
83 pub fn with_x(self, x: usize) -> Self {
86 Self {
87 reference: self.reference.with_x(x),
88 ..self
89 }
90 }
91
92 pub fn with_y(self, y: usize) -> Self {
95 Self {
96 reference: self.reference.with_y(y),
97 ..self
98 }
99 }
100
101 pub fn without_sheet_name(self) -> Self {
102 Self {
103 sheet_name: None,
104 ..self
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use crate::*;
112
113 #[test]
114 fn contains_different_name() {
115 let a1_a = A1 {
116 sheet_name: Some("Something".to_string()),
117 reference: RangeOrCell::Cell((1, 1).into()),
118 };
119 let a1_b = A1 {
120 sheet_name: Some("Something else".to_string()),
121 reference: RangeOrCell::Cell((1, 1).into()),
122 };
123
124 assert!(!a1_a.contains(&a1_b));
125 }
126
127 #[test]
128 fn contains_true() {
129 let a1_a = A1 {
130 sheet_name: None,
131 reference: RangeOrCell::Cell((1, 1).into()),
132 };
133 let a1_b = A1 {
134 sheet_name: None,
135 reference: RangeOrCell::Cell((1, 1).into()),
136 };
137
138 assert!(a1_a.contains(&a1_b));
139 }
140
141 #[test]
142 fn shift_down() {
143 let a1 = A1 {
144 sheet_name: Some("Test1".to_string()),
145 reference: RangeOrCell::Cell((1, 1).into()),
146 };
147
148 assert_eq!("Test1!B3", a1.shift_down(1).to_string());
149 }
150
151 #[test]
152 fn shift_left() {
153 let a1 = A1 {
154 sheet_name: Some("Test1".to_string()),
155 reference: RangeOrCell::Cell((1, 1).into()),
156 };
157
158 assert_eq!("Test1!A2", a1.shift_left(1).to_string());
159 }
160
161 #[test]
162 fn shift_right() {
163 let a1 = A1 {
164 sheet_name: None,
165 reference: RangeOrCell::Cell((1, 1).into()),
166 };
167
168 assert_eq!("C2", a1.shift_right(1).to_string());
169 }
170
171 #[test]
172 fn shift_up() {
173 let a1 = A1 {
174 sheet_name: None,
175 reference: RangeOrCell::Cell((1, 1).into()),
176 };
177
178 assert_eq!("B1", a1.shift_up(1).to_string());
179 }
180
181 #[test]
182 fn with_sheet_name() {
183 let a1 = A1 {
184 sheet_name: None,
185 reference: RangeOrCell::Cell((1, 1).into()),
186 };
187
188 assert_eq!(
189 Some("foo".to_string()),
190 a1.with_sheet_name("foo").sheet_name
191 );
192 }
193
194 #[test]
195 fn with_x() {
196 let a1 = A1 {
197 sheet_name: None,
198 reference: RangeOrCell::Cell((1, 1).into()),
199 };
200
201 assert_eq!("F2", a1.with_x(5).to_string());
202 }
203
204 #[test]
205 fn with_y() {
206 let a1 = A1 {
207 sheet_name: None,
208 reference: RangeOrCell::Cell((1, 1).into()),
209 };
210
211 assert_eq!("B22", a1.with_y(21).to_string());
212 }
213
214 #[test]
215 fn without_sheet_name() {
216 let a1 = A1 {
217 sheet_name: Some("foo".to_string()),
218 reference: RangeOrCell::Cell((1, 1).into()),
219 };
220
221 assert_eq!(None, a1.without_sheet_name().sheet_name);
222 }
223}