1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
use distill_core::TypeUuidDynamic;
use erased_serde::Deserializer;
use futures::{future::BoxFuture, AsyncRead, AsyncWrite};
use serde::{Deserialize, Serialize};
use crate::{error::Result, AsyncImporter, ExportAsset, ImportOp, ImporterValue, SerdeObj};
pub const SOURCEMETADATA_VERSION: u32 = 2;
#[derive(Serialize, Deserialize)]
pub struct SourceMetadata<Options: 'static, State: 'static> {
pub version: u32,
pub importer_options: Options,
pub importer_state: State,
}
pub trait BoxedImporter: TypeUuidDynamic + Send + Sync + 'static {
fn import_boxed<'a>(
&'a self,
op: &'a mut ImportOp,
source: &'a mut (dyn AsyncRead + Unpin + Send + Sync),
options: Box<dyn SerdeObj>,
state: Box<dyn SerdeObj>,
) -> BoxFuture<'a, Result<BoxedImporterValue>>;
fn export_boxed<'a>(
&'a self,
output: &'a mut (dyn AsyncWrite + Unpin + Send + Sync),
options: Box<dyn SerdeObj>,
state: Box<dyn SerdeObj>,
assets: Vec<ExportAsset>,
) -> BoxFuture<'a, Result<BoxedExportInputs>>;
fn default_options(&self) -> Box<dyn SerdeObj>;
fn default_state(&self) -> Box<dyn SerdeObj>;
fn version(&self) -> u32;
fn deserialize_metadata(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<SourceMetadata<Box<dyn SerdeObj>, Box<dyn SerdeObj>>>;
fn deserialize_options(&self, deserializer: &mut dyn Deserializer)
-> Result<Box<dyn SerdeObj>>;
fn deserialize_state(&self, deserializer: &mut dyn Deserializer) -> Result<Box<dyn SerdeObj>>;
}
impl std::fmt::Debug for dyn BoxedImporter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("BoxedImporter").field(&self.uuid()).finish()
}
}
pub struct BoxedImporterValue {
pub value: ImporterValue,
pub options: Box<dyn SerdeObj>,
pub state: Box<dyn SerdeObj>,
}
pub struct BoxedExportInputs {
pub options: Box<dyn SerdeObj>,
pub state: Box<dyn SerdeObj>,
pub value: ImporterValue,
}
impl<S, O, T> BoxedImporter for T
where
O: SerdeObj + Serialize + Default + Send + Sync + Clone + for<'a> Deserialize<'a>,
S: SerdeObj + Serialize + Default + Send + Sync + for<'a> Deserialize<'a>,
T: AsyncImporter<State = S, Options = O> + TypeUuidDynamic + Send + Sync,
{
fn import_boxed<'a>(
&'a self,
op: &'a mut ImportOp,
source: &'a mut (dyn AsyncRead + Unpin + Send + Sync),
options: Box<dyn SerdeObj>,
mut state: Box<dyn SerdeObj>,
) -> BoxFuture<'a, Result<BoxedImporterValue>> {
log::trace!("import_boxed");
Box::pin(async move {
let s = state.any_mut().downcast_mut::<S>();
let s = if let Some(s) = s {
s
} else {
panic!("Failed to downcast Importer::State");
};
let o = options.any().downcast_ref::<O>();
let o = if let Some(o) = o {
o
} else {
panic!("Failed to downcast Importer::Options");
};
log::trace!("import_boxed about to import");
let result = self.import(op, source, o, s).await?;
log::trace!("import_boxed imported");
Ok(BoxedImporterValue {
value: result,
options,
state,
})
})
}
fn export_boxed<'a>(
&'a self,
output: &'a mut (dyn AsyncWrite + Unpin + Send + Sync),
options: Box<dyn SerdeObj>,
mut state: Box<dyn SerdeObj>,
assets: Vec<ExportAsset>,
) -> BoxFuture<'a, Result<BoxedExportInputs>> {
Box::pin(async move {
let s = state.any_mut().downcast_mut::<S>();
let s = if let Some(s) = s {
s
} else {
panic!("Failed to downcast Importer::State");
};
let o = options.any().downcast_ref::<O>();
let o = if let Some(o) = o {
o
} else {
panic!("Failed to downcast Importer::Options");
};
let result = self.export(output, o, s, assets).await?;
Ok(BoxedExportInputs {
options,
state,
value: result,
})
})
}
fn default_options(&self) -> Box<dyn SerdeObj> {
Box::new(O::default())
}
fn default_state(&self) -> Box<dyn SerdeObj> {
Box::new(S::default())
}
fn version(&self) -> u32 {
T::version(self)
}
fn deserialize_metadata<'a>(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<SourceMetadata<Box<dyn SerdeObj>, Box<dyn SerdeObj>>> {
let metadata = erased_serde::deserialize::<SourceMetadata<O, S>>(deserializer)?;
Ok(SourceMetadata {
version: metadata.version,
importer_options: Box::new(metadata.importer_options),
importer_state: Box::new(metadata.importer_state),
})
}
fn deserialize_options<'a>(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Box<dyn SerdeObj>> {
Ok(Box::new(erased_serde::deserialize::<O>(deserializer)?))
}
fn deserialize_state<'a>(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Box<dyn SerdeObj>> {
Ok(Box::new(erased_serde::deserialize::<S>(deserializer)?))
}
}