xee_interpreter/function/
signature.rs

1use xee_schema_type::Xs;
2use xee_xpath_ast::ast;
3
4use super::static_function::FunctionKind;
5
6/// A function signature.
7#[derive(Debug, Clone, PartialEq)]
8pub struct Signature {
9    parameter_types: Vec<Option<ast::SequenceType>>,
10    return_type: Option<ast::SequenceType>,
11}
12
13impl Signature {
14    pub fn new(
15        parameter_types: Vec<Option<ast::SequenceType>>,
16        return_type: Option<ast::SequenceType>,
17    ) -> Self {
18        Self {
19            parameter_types,
20            return_type,
21        }
22    }
23
24    pub(crate) fn map_signature() -> Self {
25        let key = ast::SequenceType::Item(ast::Item {
26            item_type: ast::ItemType::AtomicOrUnionType(Xs::AnyAtomicType),
27            occurrence: ast::Occurrence::One,
28        });
29
30        let return_type = ast::SequenceType::Item(ast::Item {
31            item_type: ast::ItemType::Item,
32            occurrence: ast::Occurrence::Many,
33        });
34        Self {
35            parameter_types: vec![Some(key)],
36            return_type: Some(return_type),
37        }
38    }
39
40    pub(crate) fn array_signature() -> Self {
41        let position = ast::SequenceType::Item(ast::Item {
42            item_type: ast::ItemType::AtomicOrUnionType(Xs::AnyAtomicType),
43            occurrence: ast::Occurrence::One,
44        });
45
46        let return_type = ast::SequenceType::Item(ast::Item {
47            item_type: ast::ItemType::Item,
48            occurrence: ast::Occurrence::Many,
49        });
50        Self {
51            parameter_types: vec![Some(position)],
52            return_type: Some(return_type),
53        }
54    }
55
56    pub(crate) fn alternative_signatures(
57        &self,
58        function_kind: FunctionKind,
59    ) -> Vec<(Signature, Option<FunctionKind>)> {
60        match function_kind {
61            FunctionKind::ItemFirst => vec![
62                (
63                    Self {
64                        parameter_types: self.parameter_types[1..].to_vec(),
65                        return_type: self.return_type.clone(),
66                    },
67                    Some(function_kind),
68                ),
69                (self.clone(), None),
70            ],
71            FunctionKind::ItemLast => vec![
72                (
73                    Self {
74                        parameter_types: self.parameter_types[..self.parameter_types.len() - 1]
75                            .to_vec(),
76                        return_type: self.return_type.clone(),
77                    },
78                    Some(function_kind),
79                ),
80                (self.clone(), None),
81            ],
82            FunctionKind::ItemLastOptional => vec![(
83                Self {
84                    parameter_types: self.parameter_types[..self.parameter_types.len() - 1]
85                        .to_vec(),
86                    return_type: self.return_type.clone(),
87                },
88                Some(function_kind),
89            )],
90            FunctionKind::Position => vec![(self.clone(), Some(function_kind))],
91            FunctionKind::Size => vec![(self.clone(), Some(function_kind))],
92            FunctionKind::Collation => vec![
93                (
94                    Self {
95                        parameter_types: self.parameter_types[..self.parameter_types.len() - 1]
96                            .to_vec(),
97                        return_type: self.return_type.clone(),
98                    },
99                    Some(function_kind),
100                ),
101                (self.clone(), None),
102            ],
103            FunctionKind::AnonymousClosure => vec![(
104                Self {
105                    parameter_types: self.parameter_types[..self.parameter_types.len() - 1]
106                        .to_vec(),
107                    return_type: self.return_type.clone(),
108                },
109                Some(function_kind),
110            )],
111        }
112    }
113
114    /// The parameter types of the function.
115    pub fn parameter_types(&self) -> &[Option<ast::SequenceType>] {
116        &self.parameter_types
117    }
118
119    /// The return type of the function.
120    pub fn return_type(&self) -> Option<&ast::SequenceType> {
121        self.return_type.as_ref()
122    }
123
124    /// Return the arity of the function signature.
125    pub fn arity(&self) -> usize {
126        self.parameter_types.len()
127    }
128
129    /// Display representation
130    pub fn display_representation(&self) -> String {
131        let parameter_types = self
132            .parameter_types
133            .iter()
134            .map(|p| match p {
135                Some(p) => p.display_representation(),
136                None => "item()*".to_string(),
137            })
138            .collect::<Vec<_>>()
139            .join(", ");
140        let return_type = self
141            .return_type
142            .as_ref()
143            .map(|r| r.display_representation())
144            .unwrap_or_else(|| "item()*".to_string());
145        format!("({}) as {}", parameter_types, return_type)
146    }
147}
148
149impl From<ast::Signature> for Signature {
150    fn from(signature: ast::Signature) -> Self {
151        Self {
152            parameter_types: signature
153                .params
154                .into_iter()
155                .map(|p| Some(p.type_))
156                .collect(),
157            return_type: Some(signature.return_type),
158        }
159    }
160}