1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#[cfg(feature = "pretty-print")]
mod display;

use super::*;

/// The literal of array
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RangeKind {
    /// `[1, 2:3, 4:5:6]`
    Ordinal,
    /// `⁅1, 2:3, 4:5:6⁆`
    Offset,
}

/// `[0, [], [:], [::]]`
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RangeNode {
    ///  The kind of tuple.
    pub kind: RangeKind,
    /// Terms
    pub terms: Vec<RangeTermNode>,
    /// The range of the number.
    pub span: Range<u32>,
}
impl ValkyrieNode for RangeNode {
    fn get_range(&self) -> Range<usize> {
        Range { start: self.span.start as usize, end: self.span.end as usize }
    }
}
/// `[index], ⁅start : end : step⁆`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RangeTermNode {
    /// The index kind
    Index {
        /// The index of range
        index: ExpressionKind,
    },
    /// The range
    Range {
        /// The first element in range
        head: Option<ExpressionKind>,
        /// The middle element in range
        tail: Option<ExpressionKind>,
        /// The
        step: Option<ExpressionKind>,
    },
}

impl Default for RangeKind {
    fn default() -> Self {
        Self::Ordinal
    }
}

impl RangeNode {
    /// Convert to tuple if possible
    pub fn as_tuple(&self) -> Option<TupleNode> {
        let mut terms = Vec::with_capacity(self.terms.len());
        for term in &self.terms {
            terms.push(term.as_tuple()?)
        }
        Some(TupleNode { kind: TupleKind::Tuple, terms: ArgumentsList { terms }, span: self.span.clone() })
    }
}

impl RangeTermNode {
    /// Convert to tuple item if possible
    pub fn as_tuple(&self) -> Option<ArgumentTerm> {
        match self {
            RangeTermNode::Index { index } => {
                Some(ArgumentTerm { modifiers: Default::default(), key: ArgumentKey::Nothing, value: index.clone() })
            }
            RangeTermNode::Range { .. } => None,
        }
    }
}