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
80
81
82
83
84
mod display;

use super::*;

/// The kind of the parameter node
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ParameterKind {
    /// `a: Type = null`
    Expression,
    /// `T: Trait = ()`
    Generic,
}

/// `micro f(t: Type = default)` or `class F⦓T: Trait = Default⦔`
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ParametersList {
    /// The kind of the parameter node
    pub kind: ParameterKind,
    /// The raw string of the number.
    pub terms: Vec<ParameterTerm>,
}

/// `T: Type = type_expression`
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ParameterTerm {
    /// `<`
    ///
    /// The type on the left cannot be called by name, but the type on the right can be called by name.
    LMark,
    /// `>`
    ///
    /// The type on the left can be called by name, and the type on the right must be called by name.
    RMark,
    /// `#annotation modifier a: Type = default`
    Single {
        /// The modifiers apply on the parameter
        annotations: AnnotationNode,
        /// The name
        key: IdentifierNode,
        /// The type boundary of the parameter
        bound: Option<ExpressionKind>,
        /// The default value of the parameter
        default: Option<ExpressionKind>,
    },
    /// `#annotation modifier ..list: Type`
    UnpackList {
        /// The modifiers apply on the parameter
        modifiers: ModifierList,
        /// The list receiver name
        key: IdentifierNode,
        /// The type boundary of the parameter
        bound: Option<ExpressionKind>,
    },
    /// `#annotation modifier ...dict: Type`
    UnpackDict {
        /// The modifiers apply on the parameter
        modifiers: ModifierList,
        /// The dict receiver name
        key: IdentifierNode,
        /// The type boundary of the parameter
        bound: Option<ExpressionKind>,
    },
}

impl ParametersList {
    /// Create a new parameter list
    pub fn new(capacity: usize, kind: ParameterKind) -> Self {
        Self { kind, terms: Vec::with_capacity(capacity) }
    }
}

impl Default for ParameterKind {
    fn default() -> Self {
        Self::Expression
    }
}
impl Default for ParametersList {
    fn default() -> Self {
        Self { kind: ParameterKind::default(), terms: vec![] }
    }
}