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        }
104    }
105
106    /// The parameter types of the function.
107    pub fn parameter_types(&self) -> &[Option<ast::SequenceType>] {
108        &self.parameter_types
109    }
110
111    /// The return type of the function.
112    pub fn return_type(&self) -> Option<&ast::SequenceType> {
113        self.return_type.as_ref()
114    }
115
116    /// Return the arity of the function signature.
117    pub fn arity(&self) -> usize {
118        self.parameter_types.len()
119    }
120
121    /// Display representation
122    pub fn display_representation(&self) -> String {
123        let parameter_types = self
124            .parameter_types
125            .iter()
126            .map(|p| match p {
127                Some(p) => p.display_representation(),
128                None => "item()*".to_string(),
129            })
130            .collect::<Vec<_>>()
131            .join(", ");
132        let return_type = self
133            .return_type
134            .as_ref()
135            .map(|r| r.display_representation())
136            .unwrap_or_else(|| "item()*".to_string());
137        format!("({}) as {}", parameter_types, return_type)
138    }
139}
140
141impl From<ast::Signature> for Signature {
142    fn from(signature: ast::Signature) -> Self {
143        Self {
144            parameter_types: signature
145                .params
146                .into_iter()
147                .map(|p| Some(p.type_))
148                .collect(),
149            return_type: Some(signature.return_type),
150        }
151    }
152}