flutter_rust_bridge/misc/
into_into_dart.rs1use crate::codec::BaseCodec;
2use crate::for_generated::{BaseArc, StreamSinkBase};
3use crate::generalized_isolate::{IntoDart, ZeroCopyBuffer};
4#[cfg(feature = "rust-async")]
5use crate::rust_auto_opaque::{inner::RustAutoOpaqueInner, RustAutoOpaqueBase};
6use crate::rust_opaque::RustOpaqueBase;
7use std::collections::{HashMap, HashSet};
8
9pub trait IntoIntoDart<D: IntoDart> {
16 fn into_into_dart(self) -> D;
17}
18
19impl<T, D> IntoIntoDart<Vec<D>> for Vec<T>
20where
21 T: IntoIntoDart<D>,
22 Vec<D>: IntoDart,
23 D: IntoDart,
24{
25 #[inline(always)]
26 fn into_into_dart(self) -> Vec<D> {
27 self.into_iter().map(|e| e.into_into_dart()).collect()
28 }
29}
30
31impl<T, D> IntoIntoDart<Option<D>> for Option<T>
32where
33 T: IntoIntoDart<D>,
34 D: IntoDart,
35{
36 #[inline(always)]
37 fn into_into_dart(self) -> Option<D> {
38 self.map(|e| e.into_into_dart())
39 }
40}
41
42impl<T, A: BaseArc<T>> IntoIntoDart<RustOpaqueBase<T, A>> for RustOpaqueBase<T, A> {
43 #[inline(always)]
44 fn into_into_dart(self) -> RustOpaqueBase<T, A> {
45 self
46 }
47}
48
49#[cfg(feature = "rust-async")]
50impl<T, A: BaseArc<RustAutoOpaqueInner<T>>> IntoIntoDart<RustAutoOpaqueBase<T, A>>
51 for RustAutoOpaqueBase<T, A>
52{
53 #[inline(always)]
54 fn into_into_dart(self) -> RustAutoOpaqueBase<T, A> {
55 self
56 }
57}
58
59impl<T, D> IntoIntoDart<ZeroCopyBuffer<D>> for ZeroCopyBuffer<T>
60where
61 T: IntoIntoDart<D>,
62 D: IntoDart,
63 ZeroCopyBuffer<D>: IntoDart,
64{
65 #[inline(always)]
66 fn into_into_dart(self) -> ZeroCopyBuffer<D> {
67 ZeroCopyBuffer(self.0.into_into_dart())
68 }
69}
70
71impl<T, D, const C: usize> IntoIntoDart<[D; C]> for [T; C]
72where
73 T: IntoIntoDart<D>,
74 [D; C]: IntoDart,
75 D: IntoDart,
76{
77 #[inline(always)]
78 fn into_into_dart(self) -> [D; C] {
79 self.map(|e| e.into_into_dart())
80 }
81}
82
83impl<T, D> IntoIntoDart<D> for Box<T>
84where
85 T: IntoIntoDart<D>,
86 D: IntoDart,
87{
88 #[inline(always)]
89 fn into_into_dart(self) -> D {
90 (*self).into_into_dart()
91 }
92}
93
94impl<KT, KD, VT, VD, S> IntoIntoDart<HashMap<KD, VD>> for HashMap<KT, VT, S>
95where
96 KT: IntoIntoDart<KD>,
97 VT: IntoIntoDart<VD>,
98 HashMap<KD, VD>: IntoDart,
99 KD: IntoDart + std::cmp::Eq + std::hash::Hash,
100 VD: IntoDart,
101{
102 #[inline(always)]
103 fn into_into_dart(self) -> HashMap<KD, VD> {
104 self.into_iter()
105 .map(|(k, v)| (k.into_into_dart(), v.into_into_dart()))
106 .collect()
107 }
108}
109
110impl<T, D, S> IntoIntoDart<HashSet<D>> for HashSet<T, S>
111where
112 T: IntoIntoDart<D>,
113 HashSet<D>: IntoDart,
114 D: IntoDart + Eq + std::hash::Hash,
115{
116 #[inline(always)]
117 fn into_into_dart(self) -> HashSet<D> {
118 self.into_iter().map(|e| e.into_into_dart()).collect()
119 }
120}
121
122impl<T, Rust2DartCodec: BaseCodec> IntoIntoDart<StreamSinkBase<T, Rust2DartCodec>>
124 for StreamSinkBase<T, Rust2DartCodec>
125{
126 fn into_into_dart(self) -> StreamSinkBase<T, Rust2DartCodec> {
127 unreachable!()
128 }
129}
130macro_rules! impl_into_into_dart_for_tuple {
134 ($( ($($A:ident)+ ; $($AD:ident)+ ; $($N:tt)+) )*) => {$(
135 impl<$($A: IntoIntoDart<$AD>, $AD: IntoDart),+> IntoIntoDart<($($AD),+,)> for ($($A),+,)
136 where
137 $($A: IntoIntoDart<$AD>, $AD: IntoDart),+,
138 {
139 #[inline(always)]
140 fn into_into_dart(self) -> ($($AD),+,) {
141 (
142 $(
143 self.$N.into_into_dart(),
144 )+
145 )
146 }
147 }
148 )*};
149}
150
151impl_into_into_dart_for_tuple! {
152 (A ; AD ; 0)
153 (A B ; AD BD ; 0 1)
154 (A B C ; AD BD CD ; 0 1 2)
155 (A B C D ; AD BD CD DD ; 0 1 2 3)
156 (A B C D E ; AD BD CD DD ED ; 0 1 2 3 4)
157 (A B C D E F ; AD BD CD DD ED FD ; 0 1 2 3 4 5)
158 (A B C D E F G ; AD BD CD DD ED FD GD ; 0 1 2 3 4 5 6)
159 (A B C D E F G H ; AD BD CD DD ED FD GD HD ; 0 1 2 3 4 5 6 7)
160 (A B C D E F G H I ; AD BD CD DD ED FD GD HD ID ; 0 1 2 3 4 5 6 7 8)
161 (A B C D E F G H I J ; AD BD CD DD ED FD GD HD ID JD ; 0 1 2 3 4 5 6 7 8 9)
162}
163
164macro_rules! impl_into_into_dart_by_self {
169 ($t:ty) => {
170 impl IntoIntoDart<$t> for $t {
171 #[inline(always)]
172 fn into_into_dart(self) -> $t {
173 self
174 }
175 }
176 };
177}
178
179impl_into_into_dart_by_self!(u8);
182impl_into_into_dart_by_self!(i8);
183impl_into_into_dart_by_self!(u16);
184impl_into_into_dart_by_self!(i16);
185impl_into_into_dart_by_self!(u32);
186impl_into_into_dart_by_self!(i32);
187impl_into_into_dart_by_self!(u64);
188impl_into_into_dart_by_self!(i64);
189impl_into_into_dart_by_self!(u128);
190impl_into_into_dart_by_self!(i128);
191impl_into_into_dart_by_self!(f32);
192impl_into_into_dart_by_self!(f64);
193impl_into_into_dart_by_self!(bool);
194impl_into_into_dart_by_self!(());
195impl_into_into_dart_by_self!(usize);
196impl_into_into_dart_by_self!(isize);
197impl_into_into_dart_by_self!(String);
198impl_into_into_dart_by_self!(char);
199#[cfg(feature = "dart-opaque")]
200impl_into_into_dart_by_self!(crate::dart_opaque::DartOpaque);
201#[cfg(not(target_family = "wasm"))]
202impl_into_into_dart_by_self!(allo_isolate::ffi::DartCObject);
203#[cfg(target_family = "wasm")]
204impl_into_into_dart_by_self!(wasm_bindgen::JsValue);
205#[cfg(feature = "uuid")]
206impl_into_into_dart_by_self!(uuid::Uuid);
207#[cfg(feature = "backtrace")]
208impl_into_into_dart_by_self!(backtrace::Backtrace);
209#[cfg(feature = "anyhow")]
210impl_into_into_dart_by_self!(anyhow::Error);
211#[cfg(feature = "chrono")]
215mod chrono_impls {
216 use super::IntoIntoDart;
217 use chrono::{Local, Utc};
218 impl_into_into_dart_by_self!(chrono::Duration);
219 impl_into_into_dart_by_self!(chrono::NaiveDateTime);
220 impl_into_into_dart_by_self!(chrono::DateTime<Local>);
221 impl_into_into_dart_by_self!(chrono::DateTime<Utc>);
222}
223
224#[cfg(test)]
225mod tests {
226 #[cfg(not(target_family = "wasm"))]
227 #[test]
228 fn test_zero_copy_buffer() {
229 use crate::misc::into_into_dart::IntoIntoDart;
230 let raw: allo_isolate::ZeroCopyBuffer<Vec<u8>> = allo_isolate::ZeroCopyBuffer(vec![10]);
231 assert_eq!(raw.into_into_dart().0, vec![10]);
232 }
233}