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