cas_parser/parser/ast/
range.rs

1use crate::parser::{ast::expr::Expr, fmt::Latex};
2use std::fmt;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7/// Whether a range is inclusive or exclusive.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10pub enum RangeKind {
11    /// A half-open range, `[start, end)`.
12    HalfOpen,
13
14    /// A closed range, `[start, end]`.
15    Closed,
16}
17
18/// A range expression, written as `start..end` for a half-open range (`[start, end)`), or
19/// `start..=end` for a closed range (`[start, end]`).
20#[derive(Debug, Clone, PartialEq, Eq)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub struct Range {
23    /// The start of the range.
24    pub start: Box<Expr>,
25
26    /// The end of the range.
27    pub end: Box<Expr>,
28
29    /// Whether the range is inclusive or exclusive.
30    pub kind: RangeKind,
31
32    /// The region of the source code that this literal was parsed from.
33    pub span: std::ops::Range<usize>,
34}
35
36impl Range {
37    /// Returns the span of the `range` expression.
38    pub fn span(&self) -> std::ops::Range<usize> {
39        self.span.clone()
40    }
41}
42
43impl std::fmt::Display for Range {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        match self.kind {
46            RangeKind::HalfOpen => write!(f, "{} .. {}", self.start, self.end),
47            RangeKind::Closed => write!(f, "{} ..= {}", self.start, self.end),
48        }
49    }
50}
51
52impl Latex for Range {
53    fn fmt_latex(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        match self.kind {
55            RangeKind::HalfOpen => write!(f, "\\left[{}, {}\\right)", self.start, self.end),
56            RangeKind::Closed => write!(f, "\\left[{}, {}\\right]", self.start, self.end),
57        }
58    }
59}