icu_provider/export/
mod.rs1mod payload;
11
12#[doc(hidden)] pub use payload::ExportBox;
14pub use payload::ExportMarker;
15
16use crate::prelude::*;
17use alloc::collections::BTreeSet;
18
19pub trait DataExporter: Sync {
21 fn put_payload(
25 &self,
26 marker: DataMarkerInfo,
27 id: DataIdentifierBorrowed,
28 payload: &DataPayload<ExportMarker>,
29 ) -> Result<(), DataError>;
30
31 fn flush_singleton(
35 &self,
36 marker: DataMarkerInfo,
37 payload: &DataPayload<ExportMarker>,
38 metadata: FlushMetadata,
39 ) -> Result<(), DataError> {
40 self.put_payload(marker, Default::default(), payload)?;
41 self.flush(marker, metadata)
42 }
43
44 fn flush(&self, _marker: DataMarkerInfo, _metadata: FlushMetadata) -> Result<(), DataError> {
48 Ok(())
49 }
50
51 fn close(&mut self) -> Result<ExporterCloseMetadata, DataError> {
55 Ok(ExporterCloseMetadata::default())
56 }
57}
58
59#[derive(Debug, Default)]
60#[allow(clippy::exhaustive_structs)] pub struct ExporterCloseMetadata(pub Option<Box<dyn core::any::Any>>);
63
64#[non_exhaustive]
66#[derive(Debug, Copy, Clone, Default)]
67pub struct FlushMetadata {
68 pub supports_dry_provider: bool,
71 pub checksum: Option<u64>,
73}
74
75impl DataExporter for Box<dyn DataExporter> {
76 fn put_payload(
77 &self,
78 marker: DataMarkerInfo,
79 id: DataIdentifierBorrowed,
80 payload: &DataPayload<ExportMarker>,
81 ) -> Result<(), DataError> {
82 (**self).put_payload(marker, id, payload)
83 }
84
85 fn flush_singleton(
86 &self,
87 marker: DataMarkerInfo,
88 payload: &DataPayload<ExportMarker>,
89 metadata: FlushMetadata,
90 ) -> Result<(), DataError> {
91 (**self).flush_singleton(marker, payload, metadata)
92 }
93
94 fn flush(&self, marker: DataMarkerInfo, metadata: FlushMetadata) -> Result<(), DataError> {
95 (**self).flush(marker, metadata)
96 }
97
98 fn close(&mut self) -> Result<ExporterCloseMetadata, DataError> {
99 (**self).close()
100 }
101}
102
103pub trait ExportableProvider: IterableDynamicDataProvider<ExportMarker> + Sync {
107 fn supported_markers(&self) -> BTreeSet<DataMarkerInfo>;
109}
110
111impl ExportableProvider for Box<dyn ExportableProvider> {
112 fn supported_markers(&self) -> BTreeSet<DataMarkerInfo> {
113 (**self).supported_markers()
114 }
115}
116
117#[macro_export]
127#[doc(hidden)] macro_rules! __make_exportable_provider {
129 ($provider:ty, [ $($(#[$cfg:meta])? $struct_m:ty),+, ]) => {
130 impl $crate::export::ExportableProvider for $provider {
131 fn supported_markers(&self) -> alloc::collections::BTreeSet<$crate::DataMarkerInfo> {
132 alloc::collections::BTreeSet::from_iter([
133 $(
134 $(#[$cfg])?
135 <$struct_m>::INFO,
136 )+
137 ])
138 }
139 }
140
141 $crate::dynutil::impl_dynamic_data_provider!(
142 $provider,
143 [ $($(#[$cfg])? $struct_m),+, ],
144 $crate::export::ExportMarker
145 );
146
147 $crate::dynutil::impl_iterable_dynamic_data_provider!(
148 $provider,
149 [ $($(#[$cfg])? $struct_m),+, ],
150 $crate::export::ExportMarker
151 );
152 };
153}
154#[doc(inline)]
155pub use __make_exportable_provider as make_exportable_provider;
156
157#[derive(Default)]
159pub struct MultiExporter(Vec<Box<dyn DataExporter>>);
160
161impl MultiExporter {
162 pub const fn new(exporters: Vec<Box<dyn DataExporter>>) -> Self {
164 Self(exporters)
165 }
166}
167
168impl core::fmt::Debug for MultiExporter {
169 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170 f.debug_struct("MultiExporter")
171 .field("0", &format!("vec[len = {}]", self.0.len()))
172 .finish()
173 }
174}
175
176impl DataExporter for MultiExporter {
177 fn put_payload(
178 &self,
179 marker: DataMarkerInfo,
180 id: DataIdentifierBorrowed,
181 payload: &DataPayload<ExportMarker>,
182 ) -> Result<(), DataError> {
183 self.0
184 .iter()
185 .try_for_each(|e| e.put_payload(marker, id, payload))
186 }
187
188 fn flush_singleton(
189 &self,
190 marker: DataMarkerInfo,
191 payload: &DataPayload<ExportMarker>,
192 metadata: FlushMetadata,
193 ) -> Result<(), DataError> {
194 self.0
195 .iter()
196 .try_for_each(|e| e.flush_singleton(marker, payload, metadata))
197 }
198
199 fn flush(&self, marker: DataMarkerInfo, metadata: FlushMetadata) -> Result<(), DataError> {
200 self.0.iter().try_for_each(|e| e.flush(marker, metadata))
201 }
202
203 fn close(&mut self) -> Result<ExporterCloseMetadata, DataError> {
204 Ok(ExporterCloseMetadata(Some(Box::new(
205 self.0.iter_mut().try_fold(vec![], |mut m, e| {
206 m.push(e.close()?.0);
207 Ok::<_, DataError>(m)
208 })?,
209 ))))
210 }
211}