1use serde_json_bytes::Value as JSON;
2use shape::Shape;
3
4use super::ApplyToError;
5use super::MethodArgs;
6use super::VarsWithPathsMap;
7use super::immutable::InputPath;
8use super::location::WithRange;
9use crate::connectors::json_selection::ShapeContext;
10use crate::connectors::spec::ConnectSpec;
11
12mod common;
13
14mod future;
23mod public;
24
25#[cfg(test)]
26mod tests;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub(super) enum ArrowMethod {
30 As,
32 Echo,
33 Map,
34 Match,
35 First,
36 Last,
37 Slice,
38 Size,
39 Entries,
40 JsonParse,
41 JsonStringify,
42 JoinNotNull,
43 Filter,
44 Find,
45 Gte,
46 Lte,
47 Eq,
48 Ne,
49 Or,
50 And,
51 Gt,
52 Lt,
53 Not,
54 In,
55 Contains,
56 Get,
57 ToString,
58 ParseInt,
59 Add,
60 Sub,
61 Mul,
62 Div,
63 Mod,
64 KeysToCamelCase,
65 KeysToCamelCaseDeep,
66
67 TypeOf,
69 MatchIf,
70 Has,
71 Keys,
72 Values,
73}
74
75#[macro_export]
76macro_rules! impl_arrow_method {
77 ($struct_name:ident, $impl_fn_name:ident, $shape_fn_name:ident) => {
78 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
79 pub(crate) struct $struct_name;
80 impl $crate::connectors::json_selection::methods::ArrowMethodImpl for $struct_name {
81 fn apply(
82 &self,
83 method_name: &WithRange<String>,
84 method_args: Option<&MethodArgs>,
85 data: &JSON,
86 vars: &VarsWithPathsMap,
87 input_path: &InputPath<JSON>,
88 spec: $crate::connectors::spec::ConnectSpec,
89 ) -> (Option<JSON>, Vec<ApplyToError>) {
90 $impl_fn_name(method_name, method_args, data, vars, input_path, spec)
91 }
92
93 fn shape(
94 &self,
95 context: &$crate::connectors::json_selection::apply_to::ShapeContext,
96 method_name: &WithRange<String>,
97 method_args: Option<&MethodArgs>,
98 input_shape: Shape,
99 dollar_shape: Shape,
100 ) -> Shape {
101 $shape_fn_name(context, method_name, method_args, input_shape, dollar_shape)
102 }
103 }
104 };
105}
106
107#[allow(dead_code)] pub(super) trait ArrowMethodImpl {
109 fn apply(
110 &self,
111 method_name: &WithRange<String>,
112 method_args: Option<&MethodArgs>,
113 data: &JSON,
114 vars: &VarsWithPathsMap,
115 input_path: &InputPath<JSON>,
116 spec: ConnectSpec,
117 ) -> (Option<JSON>, Vec<ApplyToError>);
118
119 fn shape(
120 &self,
121 context: &ShapeContext,
122 method_name: &WithRange<String>,
127 method_args: Option<&MethodArgs>,
131 input_shape: Shape,
134 dollar_shape: Shape,
137 ) -> Shape;
138}
139
140impl std::ops::Deref for ArrowMethod {
143 type Target = dyn ArrowMethodImpl;
144
145 fn deref(&self) -> &Self::Target {
146 match self {
147 Self::As => &public::AsMethod,
149 Self::Echo => &public::EchoMethod,
150 Self::Map => &public::MapMethod,
151 Self::Match => &public::MatchMethod,
152 Self::First => &public::FirstMethod,
153 Self::Last => &public::LastMethod,
154 Self::Slice => &public::SliceMethod,
155 Self::Size => &public::SizeMethod,
156 Self::Entries => &public::EntriesMethod,
157 Self::JsonParse => &public::JsonParseMethod,
158 Self::JsonStringify => &public::JsonStringifyMethod,
159 Self::JoinNotNull => &public::JoinNotNullMethod,
160 Self::Filter => &public::FilterMethod,
161 Self::Find => &public::FindMethod,
162 Self::Gte => &public::GteMethod,
163 Self::Lte => &public::LteMethod,
164 Self::Eq => &public::EqMethod,
165 Self::Ne => &public::NeMethod,
166 Self::Or => &public::OrMethod,
167 Self::And => &public::AndMethod,
168 Self::Gt => &public::GtMethod,
169 Self::Lt => &public::LtMethod,
170 Self::Not => &public::NotMethod,
171 Self::In => &public::InMethod,
172 Self::Contains => &public::ContainsMethod,
173 Self::Get => &public::GetMethod,
174 Self::ToString => &public::ToStringMethod,
175 Self::ParseInt => &public::ParseIntMethod,
176 Self::Add => &public::AddMethod,
177 Self::Sub => &public::SubMethod,
178 Self::Mul => &public::MulMethod,
179 Self::Div => &public::DivMethod,
180 Self::Mod => &public::ModMethod,
181 Self::KeysToCamelCase => &public::KeysToCamelCaseMethod,
182 Self::KeysToCamelCaseDeep => &public::KeysToCamelCaseDeepMethod,
183
184 Self::TypeOf => &future::TypeOfMethod,
186 Self::MatchIf => &future::MatchIfMethod,
187 Self::Has => &future::HasMethod,
188 Self::Keys => &future::KeysMethod,
189 Self::Values => &future::ValuesMethod,
190 }
191 }
192}
193
194impl ArrowMethod {
195 pub(super) fn lookup(name: &str) -> Option<Self> {
199 let method_opt = match name {
200 "as" => Some(Self::As),
201 "echo" => Some(Self::Echo),
202 "map" => Some(Self::Map),
203 "eq" => Some(Self::Eq),
204 "match" => Some(Self::Match),
205 "matchIf" | "match_if" => Some(Self::MatchIf),
209 "typeof" => Some(Self::TypeOf),
210 "add" => Some(Self::Add),
211 "sub" => Some(Self::Sub),
212 "mul" => Some(Self::Mul),
213 "div" => Some(Self::Div),
214 "mod" => Some(Self::Mod),
215 "first" => Some(Self::First),
216 "last" => Some(Self::Last),
217 "slice" => Some(Self::Slice),
218 "size" => Some(Self::Size),
219 "has" => Some(Self::Has),
220 "get" => Some(Self::Get),
221 "keys" => Some(Self::Keys),
222 "values" => Some(Self::Values),
223 "entries" => Some(Self::Entries),
224 "not" => Some(Self::Not),
225 "or" => Some(Self::Or),
226 "and" => Some(Self::And),
227 "jsonParse" => Some(Self::JsonParse),
228 "jsonStringify" => Some(Self::JsonStringify),
229 "joinNotNull" => Some(Self::JoinNotNull),
230 "filter" => Some(Self::Filter),
231 "find" => Some(Self::Find),
232 "gte" => Some(Self::Gte),
233 "lte" => Some(Self::Lte),
234 "ne" => Some(Self::Ne),
235 "gt" => Some(Self::Gt),
236 "lt" => Some(Self::Lt),
237 "in" => Some(Self::In),
238 "contains" => Some(Self::Contains),
239 "toString" => Some(Self::ToString),
240 "parseInt" => Some(Self::ParseInt),
241 "keysToCamelCase" => Some(Self::KeysToCamelCase),
242 "keysToCamelCaseDeep" => Some(Self::KeysToCamelCaseDeep),
243 _ => None,
244 };
245
246 match method_opt {
247 Some(method) if cfg!(test) || method.is_public() => Some(method),
248 _ => None,
249 }
250 }
251
252 pub(super) const fn is_public(&self) -> bool {
253 matches!(
257 self,
258 Self::As
259 | Self::Echo
260 | Self::Map
261 | Self::Match
262 | Self::First
263 | Self::Last
264 | Self::Slice
265 | Self::Size
266 | Self::Entries
267 | Self::JsonParse
268 | Self::JsonStringify
269 | Self::JoinNotNull
270 | Self::Filter
271 | Self::Find
272 | Self::Gte
273 | Self::Lte
274 | Self::Eq
275 | Self::Ne
276 | Self::Or
277 | Self::And
278 | Self::Gt
279 | Self::Lt
280 | Self::Not
281 | Self::In
282 | Self::Contains
283 | Self::Get
284 | Self::ToString
285 | Self::ParseInt
286 | Self::Add
287 | Self::Sub
288 | Self::Mul
289 | Self::Div
290 | Self::Mod
291 | Self::KeysToCamelCase
292 | Self::KeysToCamelCaseDeep
293 )
294 }
295}