spreadsheet_ods/
refs.rs

1//!
2//! Defines types for cell references.
3//!
4
5use crate::refs::format_refs::{
6    fmt_cell_range, fmt_cell_ref, fmt_col, fmt_col_range, fmt_row, fmt_row_range,
7};
8use crate::refs::parser::CRCode::{CRCellRange, CRCellRef, CRColRange, CRRowRange};
9use crate::refs::parser::{CRCode, KTokenizerError};
10use crate::OdsError;
11use get_size::GetSize;
12use get_size_derive::GetSize;
13use kparse::provider::StdTracker;
14use kparse::Track;
15use std::fmt;
16use std::fmt::{Display, Formatter};
17
18mod format;
19mod parser;
20
21/// Basic cell reference.
22#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, GetSize)]
23pub struct CRow {
24    /// Row reference is fixed.
25    row_abs: bool,
26    /// Row.
27    row: u32,
28}
29
30impl CRow {
31    /// Row
32    pub fn new(row: u32) -> Self {
33        Self {
34            row_abs: false,
35            row,
36        }
37    }
38
39    /// Row
40    pub fn row(&self) -> u32 {
41        self.row
42    }
43
44    /// Row
45    pub fn set_row(&mut self, row: u32) {
46        self.row = row;
47    }
48
49    /// "$" row reference
50    pub fn row_abs(&self) -> bool {
51        self.row_abs
52    }
53
54    /// "$" row reference
55    pub fn set_row_abs(&mut self, abs: bool) {
56        self.row_abs = abs;
57    }
58
59    /// Makes this CellReference into an absolute reference.
60    pub fn absolute(mut self) -> Self {
61        self.row_abs = true;
62        self
63    }
64
65    /// Makes this CellReference into an absolute reference.
66    /// The column remains relative, the row is fixed.
67    pub fn absolute_row(mut self) -> Self {
68        self.row_abs = true;
69        self
70    }
71}
72
73impl Display for CRow {
74    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
75        fmt_row(f, self)
76    }
77}
78
79/// Basic cell reference.
80#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, GetSize)]
81pub struct CCol {
82    /// Column reference is fixed.
83    col_abs: bool,
84    /// Column.
85    col: u32,
86}
87
88impl CCol {
89    /// Col
90    pub fn new(col: u32) -> Self {
91        Self {
92            col_abs: false,
93            col,
94        }
95    }
96
97    /// Column
98    pub fn col(&self) -> u32 {
99        self.col
100    }
101
102    /// Column
103    pub fn set_col(&mut self, col: u32) {
104        self.col = col;
105    }
106
107    /// "$" column reference
108    pub fn col_abs(&self) -> bool {
109        self.col_abs
110    }
111
112    /// "$" column reference
113    pub fn set_col_abs(&mut self, abs: bool) {
114        self.col_abs = abs;
115    }
116
117    /// Makes this CellReference into an absolute reference.
118    pub fn absolute(mut self) -> Self {
119        self.col_abs = true;
120        self
121    }
122
123    /// Makes this CellReference into an absolute reference.
124    /// The row remains relative, the column is fixed.
125    pub fn absolute_col(mut self) -> Self {
126        self.col_abs = true;
127        self
128    }
129}
130
131impl Display for CCol {
132    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
133        fmt_col(f, self)
134    }
135}
136
137/// A reference to a cell, possibly in another sheet in another file.
138/// ```
139/// use spreadsheet_ods::CellRef;
140/// let c1 = CellRef::local(5,2);
141/// let c2 = CellRef::local(7,4).absolute_col();
142/// let c3 = CellRef::remote("spreadsheet-2", 9,6);
143/// let c4 = CellRef::try_from(".A6");
144/// ```
145#[derive(Default, Debug, Clone, PartialEq, Eq, GetSize)]
146pub struct CellRef {
147    /// External reference.
148    iri: Option<String>,
149    /// sheet reference.
150    table: Option<String>,
151    /// Cell reference.
152    row: CRow,
153    col: CCol,
154}
155
156impl CellRef {
157    /// New CellRef with all possible parameters.
158    pub fn new_all(
159        iri: Option<String>,
160        table: Option<String>,
161        row_abs: bool,
162        row: u32,
163        col_abs: bool,
164        col: u32,
165    ) -> Self {
166        Self {
167            iri,
168            table,
169            row: CRow { row_abs, row },
170            col: CCol { col_abs, col },
171        }
172    }
173
174    /// New defaults.
175    pub fn new() -> Self {
176        Default::default()
177    }
178
179    /// Creates a cellref within the same table.
180    pub fn local(row: u32, col: u32) -> Self {
181        Self {
182            iri: None,
183            table: None,
184            row: CRow {
185                row_abs: false,
186                row,
187            },
188            col: CCol {
189                col_abs: false,
190                col,
191            },
192        }
193    }
194
195    /// Creates a cellref that references another table.
196    pub fn remote<S: Into<String>>(table: S, row: u32, col: u32) -> Self {
197        Self {
198            iri: None,
199            table: Some(table.into()),
200            row: CRow {
201                row_abs: false,
202                row,
203            },
204            col: CCol {
205                col_abs: false,
206                col,
207            },
208        }
209    }
210
211    /// External file
212    pub fn set_iri<S: Into<String>>(&mut self, iri: S) {
213        self.iri = Some(iri.into());
214    }
215
216    /// External file
217    pub fn iri(&self) -> Option<&String> {
218        self.iri.as_ref()
219    }
220
221    /// Table name for references into other tables.
222    pub fn set_table<S: Into<String>>(&mut self, table: S) {
223        self.table = Some(table.into());
224    }
225
226    /// Table name for references into other tables.
227    pub fn table(&self) -> Option<&String> {
228        self.table.as_ref()
229    }
230
231    /// Row
232    pub fn set_row(&mut self, row: u32) {
233        self.row.row = row;
234    }
235
236    /// Row
237    pub fn row(&self) -> u32 {
238        self.row.row
239    }
240
241    /// "$" row reference
242    pub fn set_row_abs(&mut self, abs: bool) {
243        self.row.row_abs = abs;
244    }
245
246    /// "$" row reference
247    pub fn row_abs(&self) -> bool {
248        self.row.row_abs
249    }
250
251    /// Column
252    pub fn set_col(&mut self, col: u32) {
253        self.col.col = col;
254    }
255
256    /// Column
257    pub fn col(&self) -> u32 {
258        self.col.col
259    }
260
261    /// "$" column reference
262    pub fn set_col_abs(&mut self, abs: bool) {
263        self.col.col_abs = abs;
264    }
265
266    /// "$" column reference
267    pub fn col_abs(&self) -> bool {
268        self.col.col_abs
269    }
270
271    /// Returns a cell reference for a formula.
272    pub fn to_formula(&self) -> String {
273        let mut buf = String::new();
274        buf.push('[');
275        let _ = fmt_cell_ref(&mut buf, self);
276        buf.push(']');
277
278        buf
279    }
280
281    /// Makes this CellReference into an absolute reference.
282    pub fn absolute(mut self) -> Self {
283        self.col.col_abs = true;
284        self.row.row_abs = true;
285        self
286    }
287
288    /// Makes this CellReference into an absolute reference.
289    /// The column remains relative, the row is fixed.
290    pub fn absolute_row(mut self) -> Self {
291        self.row.row_abs = true;
292        self
293    }
294
295    /// Makes this CellReference into an absolute reference.
296    /// The row remains relative, the column is fixed.
297    pub fn absolute_col(mut self) -> Self {
298        self.col.col_abs = true;
299        self
300    }
301}
302
303impl TryFrom<&str> for CellRef {
304    type Error = OdsError;
305
306    fn try_from(s: &str) -> Result<Self, Self::Error> {
307        parse_cellref(s)
308    }
309}
310
311impl Display for CellRef {
312    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
313        fmt_cell_ref(f, self)
314    }
315}
316
317/// A cell-range.
318///
319/// As usual for a spreadsheet this is meant as inclusive from and to.
320///
321/// // ```
322/// // let r1 = CellRange::local(0, 0, 9, 9);
323/// // let r2 = CellRange::origin_span(5, 5, (3, 3));
324/// // ```
325///
326#[derive(Debug, Default, Clone, PartialEq, Eq, GetSize)]
327pub struct CellRange {
328    /// URI to an external source for this range.
329    iri: Option<String>,
330    /// First sheet for the range.
331    from_table: Option<String>,
332    /// From
333    from_row: CRow,
334    from_col: CCol,
335    /// Second sheet for the range. Can be empty if only one sheet is involved.
336    to_table: Option<String>,
337    /// To
338    to_row: CRow,
339    to_col: CCol,
340}
341
342impl CellRange {
343    /// Create a CellRange with all possible arguments.
344    #[allow(clippy::too_many_arguments)]
345    pub fn new_all(
346        iri: Option<String>,
347        from_table: Option<String>,
348        from_row_abs: bool,
349        from_row: u32,
350        from_col_abs: bool,
351        from_col: u32,
352        to_table: Option<String>,
353        to_row_abs: bool,
354        to_row: u32,
355        to_col_abs: bool,
356        to_col: u32,
357    ) -> Self {
358        Self {
359            iri,
360            from_table,
361            from_row: CRow {
362                row_abs: from_row_abs,
363                row: from_row,
364            },
365            from_col: CCol {
366                col_abs: from_col_abs,
367                col: from_col,
368            },
369            to_table,
370            to_row: CRow {
371                row_abs: to_row_abs,
372                row: to_row,
373            },
374            to_col: CCol {
375                col_abs: to_col_abs,
376                col: to_col,
377            },
378        }
379    }
380
381    /// Empty
382    pub fn new() -> Self {
383        Default::default()
384    }
385
386    /// Creates the cell range from from + to data.
387    ///
388    /// Panic
389    ///
390    /// If row > to_row or col > to_col.
391    pub fn local(row: u32, col: u32, to_row: u32, to_col: u32) -> Self {
392        assert!(row <= to_row);
393        assert!(col <= to_col);
394        Self {
395            iri: None,
396            from_table: None,
397            from_row: CRow {
398                row_abs: false,
399                row,
400            },
401            from_col: CCol {
402                col_abs: false,
403                col,
404            },
405            to_table: None,
406            to_row: CRow {
407                row_abs: false,
408                row: to_row,
409            },
410            to_col: CCol {
411                col_abs: false,
412                col: to_col,
413            },
414        }
415    }
416
417    /// Creates the cell range from from + to data.
418    ///
419    /// Panic
420    ///
421    /// If row > to_row or col > to_col.
422    pub fn remote<S: Into<String>>(table: S, row: u32, col: u32, to_row: u32, to_col: u32) -> Self {
423        assert!(row <= to_row);
424        assert!(col <= to_col);
425        Self {
426            iri: None,
427            from_table: Some(table.into()),
428            from_row: CRow {
429                row_abs: false,
430                row,
431            },
432            from_col: CCol {
433                col_abs: false,
434                col,
435            },
436            to_table: None,
437            to_row: CRow {
438                row_abs: false,
439                row: to_row,
440            },
441            to_col: CCol {
442                col_abs: false,
443                col: to_col,
444            },
445        }
446    }
447
448    /// Creates the cell range from origin + spanning data.
449    ///
450    /// Panic
451    ///
452    /// Both span values must be > 0.
453    pub fn origin_span(row: u32, col: u32, span: (u32, u32)) -> Self {
454        assert!(span.0 > 0);
455        assert!(span.1 > 0);
456        Self {
457            iri: None,
458            from_table: None,
459            from_row: CRow {
460                row_abs: false,
461                row,
462            },
463            from_col: CCol {
464                col_abs: false,
465                col,
466            },
467            to_table: None,
468            to_row: CRow {
469                row_abs: false,
470                row: row + span.0 - 1,
471            },
472            to_col: CCol {
473                col_abs: false,
474                col: col + span.1 - 1,
475            },
476        }
477    }
478
479    /// External file
480    pub fn set_iri<S: Into<String>>(&mut self, iri: S) {
481        self.iri = Some(iri.into());
482    }
483
484    /// External file
485    pub fn iri(&self) -> Option<&String> {
486        self.iri.as_ref()
487    }
488
489    /// Table name for references into other tables.
490    pub fn set_table<S: Into<String>>(&mut self, table: S) {
491        self.from_table = Some(table.into());
492    }
493
494    /// Table name for references into other tables.
495    pub fn table(&self) -> Option<&String> {
496        self.from_table.as_ref()
497    }
498
499    /// Row
500    pub fn set_row(&mut self, row: u32) {
501        self.from_row.row = row;
502    }
503
504    /// Row
505    pub fn row(&self) -> u32 {
506        self.from_row.row
507    }
508
509    /// "$" row reference
510    pub fn set_row_abs(&mut self, abs: bool) {
511        self.from_row.row_abs = abs;
512    }
513
514    /// "$" row reference
515    pub fn row_abs(&self) -> bool {
516        self.from_row.row_abs
517    }
518
519    /// Column
520    pub fn set_col(&mut self, col: u32) {
521        self.from_col.col = col;
522    }
523
524    /// Column
525    pub fn col(&self) -> u32 {
526        self.from_col.col
527    }
528
529    /// "$" column reference
530    pub fn set_col_abs(&mut self, abs: bool) {
531        self.from_col.col_abs = abs;
532    }
533
534    /// "$" column reference
535    pub fn col_abs(&self) -> bool {
536        self.from_col.col_abs
537    }
538
539    /// Table name for references into other tables.
540    pub fn set_to_table<S: Into<String>>(&mut self, table: S) {
541        self.to_table = Some(table.into());
542    }
543
544    /// Table name for references into other tables.
545    pub fn to_table(&self) -> Option<&String> {
546        self.to_table.as_ref()
547    }
548
549    /// To row
550    pub fn set_to_row(&mut self, to_row: u32) {
551        self.to_row.row = to_row;
552    }
553
554    /// To row
555    pub fn to_row(&self) -> u32 {
556        self.to_row.row
557    }
558
559    /// "$" row reference
560    pub fn set_to_row_abs(&mut self, abs: bool) {
561        self.to_row.row_abs = abs;
562    }
563
564    /// "$" row reference
565    pub fn to_row_abs(&self) -> bool {
566        self.to_row.row_abs
567    }
568
569    /// To column
570    pub fn set_to_col(&mut self, to_col: u32) {
571        self.to_col.col = to_col;
572    }
573
574    /// To column
575    pub fn to_col(&self) -> u32 {
576        self.to_col.col
577    }
578
579    /// "$" column reference
580    pub fn set_to_col_abs(&mut self, abs: bool) {
581        self.to_col.col_abs = abs;
582    }
583
584    /// "$" column reference
585    pub fn to_col_abs(&self) -> bool {
586        self.to_col.col_abs
587    }
588
589    /// Returns a range reference for a formula.
590    pub fn to_formula(&self) -> String {
591        let mut buf = String::new();
592        buf.push('[');
593        let _ = fmt_cell_range(&mut buf, self);
594        buf.push(']');
595        buf
596    }
597
598    /// Makes this CellReference into an absolute reference.
599    pub fn absolute(mut self) -> Self {
600        self.from_col.col_abs = true;
601        self.from_row.row_abs = true;
602        self.to_col.col_abs = true;
603        self.to_row.row_abs = true;
604        self
605    }
606
607    /// Makes this CellReference into an absolute reference.
608    /// The columns remain relative, the rows are fixed.
609    pub fn absolute_rows(mut self) -> Self {
610        self.from_row.row_abs = true;
611        self.to_row.row_abs = true;
612        self
613    }
614
615    /// Makes this CellReference into an absolute reference.
616    /// The rows remain relative, the columns are fixed.
617    pub fn absolute_cols(mut self) -> Self {
618        self.from_col.col_abs = true;
619        self.to_col.col_abs = true;
620        self
621    }
622
623    /// Does the range contain the cell.
624    /// This is inclusive for to_row and to_col!
625    pub fn contains(&self, row: u32, col: u32) -> bool {
626        row >= self.from_row.row
627            && row <= self.to_row.row
628            && col >= self.from_col.col
629            && col <= self.to_col.col
630    }
631
632    /// Is this range any longer relevant, when looping rows first, then columns?
633    pub fn out_looped(&self, row: u32, col: u32) -> bool {
634        row > self.to_row.row || row == self.to_row.row && col > self.to_col.col
635    }
636}
637
638impl TryFrom<&str> for CellRange {
639    type Error = OdsError;
640
641    fn try_from(s: &str) -> Result<Self, Self::Error> {
642        parse_cellrange(s)
643    }
644}
645
646impl Display for CellRange {
647    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
648        fmt_cell_range(f, self)
649    }
650}
651
652/// A range over columns.
653#[derive(Debug, Default, Clone, PartialEq, Eq, GetSize)]
654pub struct ColRange {
655    /// External reference.
656    iri: Option<String>,
657    /// Refers to another sheet.
658    from_table: Option<String>,
659    /// Column reference is fixed.
660    from_col: CCol,
661    /// Second sheet for the range. Can be empty if only one sheet is involved.
662    to_table: Option<String>,
663    /// Column reference is fixed.
664    to_col: CCol,
665}
666
667impl ColRange {
668    /// New with all possible arguments.
669    pub fn new_all(
670        iri: Option<String>,
671        from_table: Option<String>,
672        from_col_abs: bool,
673        from_col: u32,
674        to_table: Option<String>,
675        to_col_abs: bool,
676        to_col: u32,
677    ) -> Self {
678        Self {
679            iri,
680            from_table,
681            from_col: CCol {
682                col_abs: from_col_abs,
683                col: from_col,
684            },
685            to_table,
686            to_col: CCol {
687                col_abs: to_col_abs,
688                col: to_col,
689            },
690        }
691    }
692
693    /// New range.
694    ///
695    /// Panic
696    ///
697    /// If from_col > to_col.
698    pub fn new(from_col: u32, to_col: u32) -> Self {
699        assert!(from_col <= to_col);
700        Self {
701            iri: None,
702            from_table: None,
703            from_col: CCol {
704                col_abs: false,
705                col: from_col,
706            },
707            to_table: None,
708            to_col: CCol {
709                col_abs: false,
710                col: to_col,
711            },
712        }
713    }
714
715    /// External file
716    pub fn set_iri<S: Into<String>>(&mut self, iri: S) {
717        self.iri = Some(iri.into());
718    }
719
720    /// External file
721    pub fn iri(&self) -> Option<&String> {
722        self.iri.as_ref()
723    }
724
725    /// Table name for references into other tables.
726    pub fn set_table<S: Into<String>>(&mut self, table: S) {
727        self.from_table = Some(table.into());
728    }
729
730    /// Table name for references into other tables.
731    pub fn table(&self) -> Option<&String> {
732        self.from_table.as_ref()
733    }
734
735    /// Column
736    pub fn set_col(&mut self, col: u32) {
737        self.from_col.col = col;
738    }
739
740    /// Column
741    pub fn col(&self) -> u32 {
742        self.from_col.col
743    }
744
745    /// "$" column reference
746    pub fn set_col_abs(&mut self, abs: bool) {
747        self.from_col.col_abs = abs;
748    }
749
750    /// "$" column reference
751    pub fn col_abs(&self) -> bool {
752        self.from_col.col_abs
753    }
754
755    /// Table name for references into other tables.
756    pub fn set_to_table<S: Into<String>>(&mut self, table: S) {
757        self.to_table = Some(table.into());
758    }
759
760    /// Table name for references into other tables.
761    pub fn to_table(&self) -> Option<&String> {
762        self.to_table.as_ref()
763    }
764
765    /// To column
766    pub fn set_to_col(&mut self, to_col: u32) {
767        self.to_col.col = to_col;
768    }
769
770    /// To column
771    pub fn to_col(&self) -> u32 {
772        self.to_col.col
773    }
774
775    /// "$" column reference
776    pub fn set_to_col_abs(&mut self, abs: bool) {
777        self.to_col.col_abs = abs;
778    }
779
780    /// "$" column reference
781    pub fn to_col_abs(&self) -> bool {
782        self.to_col.col_abs
783    }
784
785    /// Returns a range reference for a formula.
786    pub fn to_formula(&self) -> String {
787        let mut buf = String::new();
788        buf.push('[');
789        let _ = fmt_col_range(&mut buf, self);
790        buf.push(']');
791        buf
792    }
793
794    /// Makes this CellReference into an absolute reference.
795    pub fn absolute(mut self) -> Self {
796        self.from_col.col_abs = true;
797        self.to_col.col_abs = true;
798        self
799    }
800
801    /// Is the column in this range.
802    /// The range is inclusive with the to_col.
803    pub fn contains(&self, col: u32) -> bool {
804        col >= self.from_col.col && col <= self.to_col.col
805    }
806}
807
808impl TryFrom<&str> for ColRange {
809    type Error = OdsError;
810
811    fn try_from(s: &str) -> Result<Self, Self::Error> {
812        parse_colrange(s)
813    }
814}
815
816impl Display for ColRange {
817    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
818        fmt_col_range(f, self)
819    }
820}
821
822/// A range over rows.
823#[derive(Debug, Default, Clone, PartialEq, Eq, GetSize)]
824pub struct RowRange {
825    /// External reference
826    iri: Option<String>,
827    /// Reference to another sheet.
828    from_table: Option<String>,
829    /// Row.
830    from_row: CRow,
831    /// Reference to a second sheet. Only needed if it's different than the
832    /// first one.
833    to_table: Option<String>,
834    /// Row.
835    to_row: CRow,
836}
837
838impl RowRange {
839    /// New with all possible parameters.
840    pub fn new_all(
841        iri: Option<String>,
842        from_table: Option<String>,
843        from_row_abs: bool,
844        from_row: u32,
845        to_table: Option<String>,
846        to_row_abs: bool,
847        to_row: u32,
848    ) -> Self {
849        Self {
850            iri,
851            from_table,
852            from_row: CRow {
853                row_abs: from_row_abs,
854                row: from_row,
855            },
856            to_table,
857            to_row: CRow {
858                row_abs: to_row_abs,
859                row: to_row,
860            },
861        }
862    }
863
864    /// New range.
865    pub fn new(from_row: u32, to_row: u32) -> Self {
866        assert!(from_row <= to_row);
867        Self {
868            iri: None,
869            from_table: None,
870            from_row: CRow {
871                row_abs: false,
872                row: from_row,
873            },
874            to_table: None,
875            to_row: CRow {
876                row_abs: false,
877                row: to_row,
878            },
879        }
880    }
881
882    /// External file
883    pub fn set_iri<S: Into<String>>(&mut self, iri: S) {
884        self.iri = Some(iri.into());
885    }
886
887    /// External file
888    pub fn iri(&self) -> Option<&String> {
889        self.iri.as_ref()
890    }
891
892    /// Table name for references into other tables.
893    pub fn set_table<S: Into<String>>(&mut self, table: S) {
894        self.from_table = Some(table.into());
895    }
896
897    /// Table name for references into other tables.
898    pub fn table(&self) -> Option<&String> {
899        self.from_table.as_ref()
900    }
901
902    /// Row
903    pub fn row(&self) -> u32 {
904        self.from_row.row
905    }
906
907    /// Row
908    pub fn set_row(&mut self, row: u32) {
909        self.from_row.row = row;
910    }
911
912    /// "$" row reference
913    pub fn set_row_abs(&mut self, abs: bool) {
914        self.from_row.row_abs = abs;
915    }
916
917    /// "$" row reference
918    pub fn row_abs(&self) -> bool {
919        self.from_row.row_abs
920    }
921
922    /// Table name for references into other tables.
923    pub fn set_to_table<S: Into<String>>(&mut self, table: S) {
924        self.to_table = Some(table.into());
925    }
926
927    /// Table name for references into other tables.
928    pub fn to_table(&self) -> Option<&String> {
929        self.to_table.as_ref()
930    }
931
932    /// To row
933    pub fn to_row(&self) -> u32 {
934        self.to_row.row
935    }
936
937    /// To row
938    pub fn set_to_row(&mut self, row: u32) {
939        self.to_row.row = row;
940    }
941
942    /// "$" row reference
943    pub fn set_to_row_abs(&mut self, abs: bool) {
944        self.to_row.row_abs = abs;
945    }
946
947    /// "$" row reference
948    pub fn to_row_abs(&self) -> bool {
949        self.to_row.row_abs
950    }
951
952    /// Returns a range reference for a formula.
953    pub fn to_formula(&self) -> String {
954        let mut buf = String::new();
955        buf.push('[');
956        let _ = fmt_row_range(&mut buf, self);
957        buf.push(']');
958        buf
959    }
960
961    /// Makes this CellReference into an absolute reference.
962    pub fn absolute(mut self) -> Self {
963        self.from_row.row_abs = true;
964        self.to_row.row_abs = true;
965        self
966    }
967
968    /// Is the row in this range.
969    /// The range is inclusive with the to_row.
970    pub fn contains(&self, row: u32) -> bool {
971        row >= self.from_row.row && row <= self.to_row.row
972    }
973}
974
975impl TryFrom<&str> for RowRange {
976    type Error = OdsError;
977
978    fn try_from(s: &str) -> Result<Self, Self::Error> {
979        parse_rowrange(s)
980    }
981}
982
983impl Display for RowRange {
984    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
985        fmt_row_range(f, self)
986    }
987}
988
989mod format_refs {
990    use crate::refs::format::{fmt_abs, fmt_col_name, fmt_row_name};
991    use crate::refs::{CCol, CRow};
992    use crate::{CellRange, CellRef, ColRange, RowRange};
993    use std::fmt;
994
995    /// Appends a simple cell reference.
996    pub(crate) fn fmt_row(f: &mut impl fmt::Write, row: &CRow) -> fmt::Result {
997        fmt_abs(f, row.row_abs())?;
998        fmt_row_name(f, row.row())?;
999        Ok(())
1000    }
1001
1002    /// Appends a simple cell reference.
1003    pub(crate) fn fmt_col(f: &mut impl fmt::Write, col: &CCol) -> fmt::Result {
1004        fmt_abs(f, col.col_abs())?;
1005        fmt_col_name(f, col.col())?;
1006        Ok(())
1007    }
1008
1009    /// Appends the cell reference
1010    pub(crate) fn fmt_cell_ref(f: &mut impl fmt::Write, cell_ref: &CellRef) -> fmt::Result {
1011        fmt_iri(f, cell_ref.iri())?;
1012        if let Some(sheet) = cell_ref.table().as_ref() {
1013            fmt_table_name(
1014                f,
1015                sheet,
1016                cell_ref.iri().is_some() || cell_ref.col_abs() || cell_ref.row_abs(),
1017            )?;
1018        }
1019        write!(f, ".")?;
1020        fmt_col(f, &cell_ref.col)?;
1021        fmt_row(f, &cell_ref.row)?;
1022        Ok(())
1023    }
1024
1025    /// Appends the range reference
1026    pub(crate) fn fmt_cell_range(f: &mut impl fmt::Write, cell_range: &CellRange) -> fmt::Result {
1027        fmt_iri(f, cell_range.iri())?;
1028        if let Some(table) = cell_range.table().as_ref() {
1029            fmt_table_name(
1030                f,
1031                table,
1032                cell_range.iri().is_some()
1033                    || cell_range.from_row.row_abs()
1034                    || cell_range.from_col.col_abs()
1035                    || cell_range.to_row.row_abs()
1036                    || cell_range.to_col.col_abs(),
1037            )?;
1038        }
1039        write!(f, ".")?;
1040        fmt_col(f, &cell_range.from_col)?;
1041        fmt_row(f, &cell_range.from_row)?;
1042        write!(f, ":")?;
1043        if let Some(to_table) = cell_range.to_table().as_ref() {
1044            fmt_table_name(
1045                f,
1046                to_table,
1047                cell_range.iri().is_some()
1048                    || cell_range.from_row.row_abs()
1049                    || cell_range.from_col.col_abs()
1050                    || cell_range.to_row.row_abs()
1051                    || cell_range.to_col.col_abs(),
1052            )?;
1053        }
1054        write!(f, ".")?;
1055        fmt_col(f, &cell_range.to_col)?;
1056        fmt_row(f, &cell_range.to_row)?;
1057        Ok(())
1058    }
1059
1060    /// Appends the cell reference
1061    pub(crate) fn fmt_col_range(f: &mut impl fmt::Write, col_range: &ColRange) -> fmt::Result {
1062        fmt_iri(f, col_range.iri())?;
1063        if let Some(sheet) = col_range.table().as_ref() {
1064            fmt_table_name(
1065                f,
1066                sheet,
1067                col_range.iri().is_some() || col_range.col_abs() || col_range.to_col_abs(),
1068            )?;
1069        }
1070        write!(f, ".")?;
1071        fmt_col(f, &col_range.from_col)?;
1072        write!(f, ":")?;
1073        if let Some(to_sheet) = col_range.to_table().as_ref() {
1074            fmt_table_name(
1075                f,
1076                to_sheet,
1077                col_range.iri().is_some() || col_range.col_abs() || col_range.to_col_abs(),
1078            )?;
1079        }
1080        write!(f, ".")?;
1081        fmt_col(f, &col_range.to_col)?;
1082        Ok(())
1083    }
1084
1085    /// Appends the cell reference
1086    pub(crate) fn fmt_row_range(f: &mut impl fmt::Write, row_range: &RowRange) -> fmt::Result {
1087        fmt_iri(f, row_range.iri())?;
1088        if let Some(table) = row_range.table().as_ref() {
1089            fmt_table_name(
1090                f,
1091                table,
1092                row_range.iri().is_some() || row_range.row_abs() || row_range.to_row_abs(),
1093            )?;
1094        }
1095        write!(f, ".")?;
1096        fmt_row(f, &row_range.from_row)?;
1097        write!(f, ":")?;
1098        if let Some(to_table) = row_range.to_table().as_ref() {
1099            fmt_table_name(
1100                f,
1101                to_table,
1102                row_range.iri().is_some() || row_range.row_abs() || row_range.to_row_abs(),
1103            )?;
1104        }
1105        write!(f, ".")?;
1106        fmt_row(f, &row_range.to_row)?;
1107        Ok(())
1108    }
1109
1110    /// Appends the IRI
1111    pub(crate) fn fmt_iri(f: &mut impl fmt::Write, iri: Option<&String>) -> fmt::Result {
1112        if let Some(iri) = iri {
1113            write!(f, "'")?;
1114            write!(f, "{}", &iri.replace('\'', "''"))?;
1115            write!(f, "'")?;
1116            write!(f, "#")?;
1117        }
1118
1119        Ok(())
1120    }
1121
1122    /// Appends the table-name
1123    pub(crate) fn fmt_table_name(
1124        f: &mut impl fmt::Write,
1125        table_name: &str,
1126        abs: bool,
1127    ) -> fmt::Result {
1128        fmt_abs(f, abs)?;
1129        if table_name.contains(|c| c == '\'' || c == ' ' || c == '.') {
1130            write!(f, "'")?;
1131            write!(f, "{}", &table_name.replace('\'', "''"))?;
1132            write!(f, "'")?;
1133        } else {
1134            write!(f, "{}", table_name)?;
1135        }
1136        Ok(())
1137    }
1138}
1139
1140/// Parse a cell reference.
1141pub fn parse_cellref(buf: &str) -> Result<CellRef, OdsError> {
1142    let trk: StdTracker<CRCode, _> = Track::new_tracker();
1143    let span = Track::new_span(&trk, buf);
1144
1145    let (rest, tok) = parser::parse_cell_ref(span)?;
1146    if rest.len() > 0 {
1147        Err(nom::Err::Error(KTokenizerError::new(CRCellRef, rest)))?
1148    } else {
1149        Ok(tok)
1150    }
1151}
1152
1153/// Parse a cell reference.
1154pub fn parse_cellrange(buf: &str) -> Result<CellRange, OdsError> {
1155    let trk: StdTracker<CRCode, _> = Track::new_tracker();
1156    let span = Track::new_span(&trk, buf);
1157
1158    let (rest, tok) = parser::parse_cell_range(span)?;
1159    if rest.len() > 0 {
1160        Err(nom::Err::Error(KTokenizerError::new(CRCellRange, rest)))?
1161    } else {
1162        Ok(tok)
1163    }
1164}
1165
1166/// Parse a cell reference.
1167pub fn parse_colrange(buf: &str) -> Result<ColRange, OdsError> {
1168    let trk: StdTracker<CRCode, _> = Track::new_tracker();
1169    let span = Track::new_span(&trk, buf);
1170
1171    let (rest, tok) = parser::parse_col_range(span)?;
1172    if rest.len() > 0 {
1173        Err(nom::Err::Error(KTokenizerError::new(CRColRange, rest)))?
1174    } else {
1175        Ok(tok)
1176    }
1177}
1178
1179/// Parse a cell reference.
1180pub fn parse_rowrange(buf: &str) -> Result<RowRange, OdsError> {
1181    let trk: StdTracker<CRCode, _> = Track::new_tracker();
1182    let span = Track::new_span(&trk, buf);
1183
1184    let (rest, tok) = parser::parse_row_range(span)?;
1185    if rest.len() > 0 {
1186        Err(nom::Err::Error(KTokenizerError::new(CRRowRange, rest)))?
1187    } else {
1188        Ok(tok)
1189    }
1190}
1191
1192/// Parse a list of range refs
1193pub fn parse_cellranges(buf: &str) -> Result<Option<Vec<CellRange>>, OdsError> {
1194    let trk: StdTracker<CRCode, _> = Track::new_tracker();
1195    let span = Track::new_span(&trk, buf);
1196
1197    match parser::parse_cell_range_list(span) {
1198        Ok((_, ranges)) => Ok(ranges),
1199        Err(err) => Err(err.into()),
1200    }
1201}
1202
1203pub(crate) fn format_cellranges(v: &[CellRange]) -> impl Display + '_ {
1204    struct Tmp<'f>(&'f [CellRange]);
1205
1206    impl<'f> Display for Tmp<'f> {
1207        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1208            for (i, range) in self.0.iter().enumerate() {
1209                if i > 0 {
1210                    write!(f, " ")?;
1211                }
1212                write!(f, "{}", range)?;
1213            }
1214            Ok(())
1215        }
1216    }
1217
1218    Tmp(v)
1219}