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 }
104 }
105
106 pub fn parameter_types(&self) -> &[Option<ast::SequenceType>] {
108 &self.parameter_types
109 }
110
111 pub fn return_type(&self) -> Option<&ast::SequenceType> {
113 self.return_type.as_ref()
114 }
115
116 pub fn arity(&self) -> usize {
118 self.parameter_types.len()
119 }
120
121 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}