1use crate::{flow_type, Config, Dummy, Flow, TypeVisitor};
4
5macro_rules! impl_wrapper {
7 ($($t:tt)*) => {
8 $($t)* {
9 type WithoutGenerics = Self;
10 type OptionInnerType = Self;
11 fn name(cfg: &Config) -> String { <T as crate::Flow>::name(cfg) }
12 fn inline(cfg: &Config) -> String { <T as crate::Flow>::inline(cfg) }
13 fn inline_flattened(cfg: &Config) -> String { <T as crate::Flow>::inline_flattened(cfg) }
14 fn visit_dependencies(v: &mut impl TypeVisitor)
15 where
16 Self: 'static,
17 {
18 <T as crate::Flow>::visit_dependencies(v);
19 }
20 fn visit_generics(v: &mut impl TypeVisitor)
21 where
22 Self: 'static,
23 {
24 <T as crate::Flow>::visit_generics(v);
25 v.visit::<T>();
26 }
27 fn decl(_: &Config) -> String { panic!("wrapper type cannot be declared") }
28 fn decl_concrete(_: &Config) -> String { panic!("wrapper type cannot be declared") }
29 }
30 };
31}
32
33macro_rules! impl_shadow {
35 (as $s:ty: $($impl:tt)*) => {
36 $($impl)* {
37 type WithoutGenerics = <$s as crate::Flow>::WithoutGenerics;
38 type OptionInnerType = <$s as crate::Flow>::OptionInnerType;
39 fn ident(cfg: &Config) -> String { <$s as crate::Flow>::ident(cfg) }
40 fn name(cfg: &Config) -> String { <$s as crate::Flow>::name(cfg) }
41 fn inline(cfg: &Config) -> String { <$s as crate::Flow>::inline(cfg) }
42 fn inline_flattened(cfg: &Config) -> String { <$s as crate::Flow>::inline_flattened(cfg) }
43 fn visit_dependencies(v: &mut impl crate::TypeVisitor)
44 where
45 Self: 'static,
46 {
47 <$s as crate::Flow>::visit_dependencies(v);
48 }
49 fn visit_generics(v: &mut impl crate::TypeVisitor)
50 where
51 Self: 'static,
52 {
53 <$s as crate::Flow>::visit_generics(v);
54 }
55 fn decl(cfg: &Config) -> String { <$s as crate::Flow>::decl(cfg) }
56 fn decl_concrete(cfg: &Config) -> String { <$s as crate::Flow>::decl_concrete(cfg) }
57 fn output_path() -> Option<std::path::PathBuf> { <$s as crate::Flow>::output_path() }
58 }
59 };
60}
61
62macro_rules! impl_flow_primitive {
63 ($rust_ty:ty, $flow_ty:expr) => {
64 impl Flow for $rust_ty {
65 type WithoutGenerics = Self;
66 type OptionInnerType = Self;
67 fn name(_: &Config) -> String {
68 $flow_ty.to_owned()
69 }
70 fn inline(cfg: &Config) -> String {
71 <Self as crate::Flow>::name(cfg)
72 }
73 }
74 };
75}
76
77impl_flow_primitive!(bool, flow_type::BOOLEAN);
79impl_flow_primitive!(i8, flow_type::NUMBER);
80impl_flow_primitive!(i16, flow_type::NUMBER);
81impl_flow_primitive!(i32, flow_type::NUMBER);
82impl_flow_primitive!(u8, flow_type::NUMBER);
83impl_flow_primitive!(u16, flow_type::NUMBER);
84impl_flow_primitive!(u32, flow_type::NUMBER);
85macro_rules! impl_flow_large_int {
88 ($($rust_ty:ty),+) => {$(
89 impl Flow for $rust_ty {
90 type WithoutGenerics = Self;
91 type OptionInnerType = Self;
92 fn name(cfg: &Config) -> String {
93 cfg.large_int().to_owned()
94 }
95 fn inline(cfg: &Config) -> String {
96 cfg.large_int().to_owned()
97 }
98 }
99 )+};
100}
101
102impl_flow_large_int!(i64, u64, i128, u128);
103impl_flow_primitive!(f32, flow_type::NUMBER);
104impl_flow_primitive!(f64, flow_type::NUMBER);
105impl_flow_primitive!(char, flow_type::STRING);
106impl_flow_primitive!(String, flow_type::STRING);
107impl_flow_primitive!(str, flow_type::STRING);
108impl_flow_primitive!((), flow_type::NULL);
109
110impl<T: Flow> Flow for Option<T> {
112 type WithoutGenerics = Self;
113 type OptionInnerType = T;
114 const IS_OPTION: bool = true;
115
116 fn name(cfg: &Config) -> String {
117 format!("?{}", T::name(cfg))
118 }
119 fn inline(cfg: &Config) -> String {
120 format!("?{}", T::inline(cfg))
121 }
122 fn visit_dependencies(v: &mut impl TypeVisitor)
123 where
124 Self: 'static,
125 {
126 <T as crate::Flow>::visit_dependencies(v);
127 }
128 fn visit_generics(v: &mut impl TypeVisitor)
129 where
130 Self: 'static,
131 {
132 <T as crate::Flow>::visit_generics(v);
133 v.visit::<T>();
134 }
135}
136
137impl<T: Flow> Flow for Vec<T> {
139 type WithoutGenerics = Vec<Dummy>;
140 type OptionInnerType = Self;
141
142 fn ident(_: &Config) -> String {
143 flow_type::READ_ONLY_ARRAY.to_owned()
144 }
145 fn name(cfg: &Config) -> String {
146 format!("{}<{}>", flow_type::READ_ONLY_ARRAY, T::name(cfg))
147 }
148 fn inline(cfg: &Config) -> String {
149 format!("{}<{}>", flow_type::READ_ONLY_ARRAY, T::inline(cfg))
150 }
151 fn visit_dependencies(v: &mut impl TypeVisitor)
152 where
153 Self: 'static,
154 {
155 <T as crate::Flow>::visit_dependencies(v);
156 }
157 fn visit_generics(v: &mut impl TypeVisitor)
158 where
159 Self: 'static,
160 {
161 <T as crate::Flow>::visit_generics(v);
162 v.visit::<T>();
163 }
164}
165
166impl_shadow!(as Vec<T>: impl<T: Flow> Flow for [T]);
168
169impl_wrapper!(impl<T: Flow + ?Sized> Flow for Box<T>);
171
172impl_wrapper!(impl<'a, T: Flow + ?Sized> Flow for &'a T);
174
175impl_wrapper!(impl<'a, T: Flow + ?Sized> Flow for &'a mut T);
177
178impl<K: Flow, V: Flow> Flow for std::collections::HashMap<K, V> {
180 type WithoutGenerics = std::collections::HashMap<Dummy, Dummy>;
181 type OptionInnerType = Self;
182
183 fn ident(_: &Config) -> String {
184 panic!()
185 }
186 fn name(cfg: &Config) -> String {
187 format!("{{ [key: {}]: {} }}", K::name(cfg), V::name(cfg))
188 }
189 fn inline(cfg: &Config) -> String {
190 format!("{{ [key: {}]: {} }}", K::inline(cfg), V::inline(cfg))
191 }
192 fn inline_flattened(cfg: &Config) -> String {
193 format!("({})", Self::inline(cfg))
194 }
195 fn visit_dependencies(v: &mut impl TypeVisitor)
196 where
197 Self: 'static,
198 {
199 K::visit_dependencies(v);
200 V::visit_dependencies(v);
201 }
202 fn visit_generics(v: &mut impl TypeVisitor)
203 where
204 Self: 'static,
205 {
206 K::visit_generics(v);
207 v.visit::<K>();
208 V::visit_generics(v);
209 v.visit::<V>();
210 }
211}
212
213impl_shadow!(as std::collections::HashMap<K, V>: impl<K: Flow, V: Flow> Flow for std::collections::BTreeMap<K, V>);
215
216impl_shadow!(as Vec<T>: impl<T: Flow> Flow for std::collections::HashSet<T>);
218
219impl_shadow!(as Vec<T>: impl<T: Flow> Flow for std::collections::BTreeSet<T>);
221
222impl_shadow!(as Vec<T>: impl<T: Flow> Flow for std::collections::VecDeque<T>);
224
225impl_shadow!(as Vec<T>: impl<T: Flow> Flow for std::collections::LinkedList<T>);
227
228macro_rules! impl_flow_tuples {
230 ( impl $($i:ident),* ) => {
231 impl<$($i: Flow),*> Flow for ($($i,)*) {
232 type WithoutGenerics = (Dummy, );
233 type OptionInnerType = Self;
234 fn name(cfg: &Config) -> String {
235 let parts: Vec<String> = vec![$($i::name(cfg)),*];
236 format!("[{}]", parts.join(", "))
237 }
238 fn inline(cfg: &Config) -> String {
239 let parts: Vec<String> = vec![$($i::inline(cfg)),*];
240 format!("[{}]", parts.join(", "))
241 }
242 fn inline_flattened(cfg: &Config) -> String {
243 format!("({})", Self::inline(cfg))
244 }
245 fn decl(_: &Config) -> String {
246 panic!("tuple cannot be declared")
247 }
248 fn decl_concrete(_: &Config) -> String {
249 panic!("tuple cannot be declared")
250 }
251 fn visit_generics(v: &mut impl TypeVisitor)
252 where
253 Self: 'static
254 {
255 $(
256 v.visit::<$i>();
257 <$i as crate::Flow>::visit_generics(v);
258 )*
259 }
260 }
261 };
262 ( $i2:ident $(, $i:ident)* ) => {
263 impl_flow_tuples!(impl $i2 $(, $i)* );
264 impl_flow_tuples!($($i),*);
265 };
266 () => {};
267}
268
269impl_flow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
270
271#[cfg(feature = "serde-json-impl")]
273impl Flow for serde_json::Value {
274 type WithoutGenerics = Self;
275 type OptionInnerType = Self;
276 fn name(_: &Config) -> String {
277 "JsonValue".to_owned()
278 }
279 fn inline(_: &Config) -> String {
280 flow_type::MIXED.to_owned()
281 }
282 fn decl(_: &Config) -> String {
283 format!("type JsonValue = {};", flow_type::MIXED)
284 }
285 fn decl_concrete(_: &Config) -> String {
286 format!("type JsonValue = {};", flow_type::MIXED)
287 }
288 fn output_path() -> Option<std::path::PathBuf> {
289 Some(std::path::PathBuf::from("JsonValue"))
290 }
291}
292
293impl Flow for std::path::PathBuf {
295 type WithoutGenerics = Self;
296 type OptionInnerType = Self;
297 fn name(_: &Config) -> String {
298 flow_type::STRING.to_owned()
299 }
300 fn inline(_: &Config) -> String {
301 flow_type::STRING.to_owned()
302 }
303}
304
305impl Flow for std::path::Path {
306 type WithoutGenerics = Self;
307 type OptionInnerType = Self;
308 fn name(_: &Config) -> String {
309 flow_type::STRING.to_owned()
310 }
311 fn inline(_: &Config) -> String {
312 flow_type::STRING.to_owned()
313 }
314}
315
316impl_wrapper!(impl<'a, T: Flow + ToOwned + ?Sized> Flow for std::borrow::Cow<'a, T>);
318
319impl<T: Flow, E: Flow> Flow for Result<T, E> {
321 type WithoutGenerics = Result<Dummy, Dummy>;
322 type OptionInnerType = Self;
323
324 fn name(cfg: &Config) -> String {
325 format!(
326 "{{| Ok: {} |}} | {{| Err: {} |}}",
327 T::name(cfg),
328 E::name(cfg)
329 )
330 }
331 fn inline(cfg: &Config) -> String {
332 format!(
333 "{{| Ok: {} |}} | {{| Err: {} |}}",
334 T::inline(cfg),
335 E::inline(cfg)
336 )
337 }
338 fn visit_dependencies(v: &mut impl TypeVisitor)
339 where
340 Self: 'static,
341 {
342 <T as crate::Flow>::visit_dependencies(v);
343 <E as crate::Flow>::visit_dependencies(v);
344 }
345 fn visit_generics(v: &mut impl TypeVisitor)
346 where
347 Self: 'static,
348 {
349 <T as crate::Flow>::visit_generics(v);
350 v.visit::<T>();
351 <E as crate::Flow>::visit_generics(v);
352 v.visit::<E>();
353 }
354}
355
356impl<T: Flow, const N: usize> Flow for [T; N] {
358 type WithoutGenerics = [Dummy; N];
359 type OptionInnerType = Self;
360
361 fn name(cfg: &Config) -> String {
362 if N > cfg.array_tuple_limit() {
363 return <Vec<T> as crate::Flow>::name(cfg);
364 }
365 format!(
366 "[{}]",
367 (0..N).map(|_| T::name(cfg)).collect::<Vec<_>>().join(", ")
368 )
369 }
370 fn inline(cfg: &Config) -> String {
371 if N > cfg.array_tuple_limit() {
372 return <Vec<T> as crate::Flow>::inline(cfg);
373 }
374 format!(
375 "[{}]",
376 (0..N)
377 .map(|_| T::inline(cfg))
378 .collect::<Vec<_>>()
379 .join(", ")
380 )
381 }
382 fn visit_dependencies(v: &mut impl TypeVisitor)
383 where
384 Self: 'static,
385 {
386 <T as crate::Flow>::visit_dependencies(v);
387 }
388 fn visit_generics(v: &mut impl TypeVisitor)
389 where
390 Self: 'static,
391 {
392 <T as crate::Flow>::visit_generics(v);
393 v.visit::<T>();
394 }
395}
396
397impl_wrapper!(impl<T: Flow + ?Sized> Flow for std::sync::Arc<T>);
399
400impl_wrapper!(impl<T: Flow + ?Sized> Flow for std::rc::Rc<T>);
402
403impl_wrapper!(impl<T: Flow> Flow for std::cell::Cell<T>);
405
406impl_wrapper!(impl<T: Flow> Flow for std::cell::RefCell<T>);
408
409impl_wrapper!(impl<T: Flow> Flow for std::sync::Mutex<T>);
411
412impl_wrapper!(impl<T: Flow> Flow for std::sync::RwLock<T>);
414
415impl_flow_primitive!(usize, flow_type::NUMBER);
417impl_flow_primitive!(isize, flow_type::NUMBER);
418
419impl_flow_primitive!(std::convert::Infallible, flow_type::EMPTY);
421
422impl_wrapper!(impl<T: Flow> Flow for std::num::Wrapping<T>);
424
425impl_wrapper!(impl<T: Flow> Flow for std::num::Saturating<T>);
427
428impl_shadow!(as u8: impl Flow for std::num::NonZeroU8);
430impl_shadow!(as u16: impl Flow for std::num::NonZeroU16);
431impl_shadow!(as u32: impl Flow for std::num::NonZeroU32);
432impl_shadow!(as u64: impl Flow for std::num::NonZeroU64);
433impl_shadow!(as u128: impl Flow for std::num::NonZeroU128);
434impl_shadow!(as usize: impl Flow for std::num::NonZeroUsize);
435impl_shadow!(as i8: impl Flow for std::num::NonZeroI8);
436impl_shadow!(as i16: impl Flow for std::num::NonZeroI16);
437impl_shadow!(as i32: impl Flow for std::num::NonZeroI32);
438impl_shadow!(as i64: impl Flow for std::num::NonZeroI64);
439impl_shadow!(as i128: impl Flow for std::num::NonZeroI128);
440impl_shadow!(as isize: impl Flow for std::num::NonZeroIsize);
441
442impl<T: ?Sized> Flow for std::marker::PhantomData<T> {
444 type WithoutGenerics = Self;
445 type OptionInnerType = Self;
446 fn name(_: &Config) -> String {
447 flow_type::VOID.to_owned()
448 }
449 fn inline(_: &Config) -> String {
450 flow_type::VOID.to_owned()
451 }
452}
453
454impl<T: Flow> Flow for std::ops::Range<T> {
456 type WithoutGenerics = std::ops::Range<Dummy>;
457 type OptionInnerType = Self;
458
459 fn ident(_: &Config) -> String {
460 panic!()
461 }
462 fn name(cfg: &Config) -> String {
463 format!("{{ +start: {}, +end: {} }}", T::name(cfg), T::name(cfg))
464 }
465 fn inline(cfg: &Config) -> String {
466 format!("{{ +start: {}, +end: {} }}", T::inline(cfg), T::inline(cfg))
467 }
468 fn inline_flattened(cfg: &Config) -> String {
469 format!("({})", Self::inline(cfg))
470 }
471 fn visit_dependencies(v: &mut impl TypeVisitor)
472 where
473 Self: 'static,
474 {
475 T::visit_dependencies(v);
476 }
477 fn visit_generics(v: &mut impl TypeVisitor)
478 where
479 Self: 'static,
480 {
481 T::visit_generics(v);
482 v.visit::<T>();
483 }
484}
485
486impl_shadow!(as std::ops::Range<T>: impl<T: Flow> Flow for std::ops::RangeInclusive<T>);
488
489impl Flow for std::time::Duration {
491 type WithoutGenerics = Self;
492 type OptionInnerType = Self;
493 fn name(_: &Config) -> String {
494 format!(
495 "{{| +secs: {}, +nanos: {} |}}",
496 flow_type::NUMBER,
497 flow_type::NUMBER
498 )
499 }
500 fn inline(cfg: &Config) -> String {
501 Self::name(cfg)
502 }
503}
504
505impl_flow_primitive!(std::time::SystemTime, flow_type::STRING);
507
508impl_flow_primitive!(std::net::IpAddr, flow_type::STRING);
510impl_flow_primitive!(std::net::Ipv4Addr, flow_type::STRING);
511impl_flow_primitive!(std::net::Ipv6Addr, flow_type::STRING);
512impl_flow_primitive!(std::net::SocketAddr, flow_type::STRING);
513impl_flow_primitive!(std::net::SocketAddrV4, flow_type::STRING);
514impl_flow_primitive!(std::net::SocketAddrV6, flow_type::STRING);
515
516#[cfg(feature = "chrono-impl")]
518impl_flow_primitive!(chrono::NaiveDate, flow_type::STRING);
519#[cfg(feature = "chrono-impl")]
520impl_flow_primitive!(chrono::NaiveTime, flow_type::STRING);
521#[cfg(feature = "chrono-impl")]
522impl_flow_primitive!(chrono::NaiveDateTime, flow_type::STRING);
523#[cfg(feature = "chrono-impl")]
524impl<T: chrono::TimeZone> Flow for chrono::DateTime<T> {
525 type WithoutGenerics = Self;
526 type OptionInnerType = Self;
527 fn name(_: &Config) -> String {
528 flow_type::STRING.to_owned()
529 }
530 fn inline(_: &Config) -> String {
531 flow_type::STRING.to_owned()
532 }
533}
534#[cfg(feature = "chrono-impl")]
535impl_flow_primitive!(chrono::Duration, flow_type::STRING);
536
537#[cfg(feature = "uuid-impl")]
539impl_flow_primitive!(uuid::Uuid, flow_type::STRING);
540
541#[cfg(feature = "url-impl")]
543impl_flow_primitive!(url::Url, flow_type::STRING);
544
545macro_rules! impl_flow_fn {
547 (impl fn() -> R) => {
549 impl<R: Flow> Flow for fn() -> R {
550 type WithoutGenerics = Self;
551 type OptionInnerType = Self;
552 fn name(cfg: &Config) -> String {
553 format!("() => {}", R::name(cfg))
554 }
555 fn inline(cfg: &Config) -> String {
556 format!("() => {}", R::inline(cfg))
557 }
558 }
559 };
560 (impl fn($($i:tt: $T:ident),+) -> R) => {
562 impl<$($T: Flow,)+ R: Flow> Flow for fn($($T),+) -> R {
563 type WithoutGenerics = Self;
564 type OptionInnerType = Self;
565 fn name(cfg: &Config) -> String {
566 let params = vec![$(format!("arg{}: {}", $i, $T::name(cfg))),+];
567 format!("({}) => {}", params.join(", "), R::name(cfg))
568 }
569 fn inline(cfg: &Config) -> String {
570 let params = vec![$(format!("arg{}: {}", $i, $T::inline(cfg))),+];
571 format!("({}) => {}", params.join(", "), R::inline(cfg))
572 }
573 fn visit_generics(v: &mut impl TypeVisitor)
574 where
575 Self: 'static,
576 {
577 $(v.visit::<$T>();)+
578 v.visit::<R>();
579 }
580 }
581 };
582}
583
584impl_flow_fn!(impl fn() -> R);
585impl_flow_fn!(impl fn(0: A) -> R);
586impl_flow_fn!(impl fn(0: A, 1: B) -> R);
587impl_flow_fn!(impl fn(0: A, 1: B, 2: C) -> R);
588impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D) -> R);
589impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E) -> R);
590impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F) -> R);
591impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G) -> R);
592impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H) -> R);
593impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I) -> R);
594impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J) -> R);
595impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K) -> R);
596impl_flow_fn!(impl fn(0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K, 11: L) -> R);