xee_interpreter/function/
signature.rs1use xee_schema_type::Xs;
2use xee_xpath_ast::ast;
3
4use super::static_function::FunctionKind;
5
6#[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 pub fn parameter_types(&self) -> &[Option<ast::SequenceType>] {
116 &self.parameter_types
117 }
118
119 pub fn return_type(&self) -> Option<&ast::SequenceType> {
121 self.return_type.as_ref()
122 }
123
124 pub fn arity(&self) -> usize {
126 self.parameter_types.len()
127 }
128
129 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}