Skip to content

Commit 9833c66

Browse files
committed
ref
1 parent 01a05fa commit 9833c66

File tree

4 files changed

+100
-43
lines changed

4 files changed

+100
-43
lines changed

provider/core/src/datagen/payload.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@ use alloc::boxed::Box;
88
use databake::{Bake, CrateEnv, TokenStream};
99
use yoke::*;
1010

11-
trait ExportableYoke {
11+
trait ExportableDataPayload {
1212
fn bake_yoke(&self, env: &CrateEnv) -> TokenStream;
1313
fn serialize_yoke(
1414
&self,
1515
serializer: &mut dyn erased_serde::Serializer,
1616
) -> Result<(), DataError>;
1717
}
1818

19-
impl<Y, C> ExportableYoke for Yoke<Y, C>
19+
impl<M: DataMarker> ExportableDataPayload for DataPayload<M>
2020
where
21-
Y: for<'a> Yokeable<'a>,
22-
for<'a> <Y as Yokeable<'a>>::Output: Bake + serde::Serialize,
21+
for<'a> <M::Yokeable as Yokeable<'a>>::Output: Bake + serde::Serialize,
2322
{
2423
fn bake_yoke(&self, ctx: &CrateEnv) -> TokenStream {
2524
self.get().bake(ctx)
@@ -40,7 +39,7 @@ where
4039
#[doc(hidden)] // exposed for make_exportable_provider
4140
#[derive(yoke::Yokeable)]
4241
pub struct ExportBox {
43-
payload: Box<dyn ExportableYoke + Sync>,
42+
payload: Box<dyn ExportableDataPayload + Sync>,
4443
}
4544

4645
impl core::fmt::Debug for ExportBox {
@@ -59,7 +58,7 @@ where
5958
{
6059
fn upcast(other: DataPayload<M>) -> DataPayload<ExportMarker> {
6160
DataPayload::from_owned(ExportBox {
62-
payload: Box::new(other.yoke),
61+
payload: Box::new(other),
6362
})
6463
}
6564
}

provider/core/src/response.rs

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ pub struct DataResponseMetadata {
7171
///
7272
/// assert_eq!("Demo", payload.get().message);
7373
/// ```
74-
pub struct DataPayload<M>
75-
where
76-
M: DataMarker,
77-
{
78-
pub(crate) yoke: Yoke<M::Yokeable, Option<Cart>>,
74+
pub struct DataPayload<M: DataMarker>(pub(crate) DataPayloadInner<M>);
75+
76+
pub(crate) enum DataPayloadInner<M: DataMarker> {
77+
Yoke(Yoke<M::Yokeable, Option<Cart>>),
78+
Ref(&'static M::Yokeable),
7979
}
8080

8181
/// The type of the "cart" that is used by `DataPayload`.
@@ -136,9 +136,10 @@ where
136136
for<'a> YokeTraitHack<<M::Yokeable as Yokeable<'a>>::Output>: Clone,
137137
{
138138
fn clone(&self) -> Self {
139-
Self {
140-
yoke: self.yoke.clone(),
141-
}
139+
Self(match &self.0 {
140+
DataPayloadInner::Yoke(yoke) => DataPayloadInner::Yoke(yoke.clone()),
141+
DataPayloadInner::Ref(r) => DataPayloadInner::Ref(*r),
142+
})
142143
}
143144
}
144145

@@ -193,17 +194,23 @@ where
193194
/// ```
194195
#[inline]
195196
pub fn from_owned(data: M::Yokeable) -> Self {
196-
Self {
197-
yoke: Yoke::new_owned(data),
198-
}
197+
Self(DataPayloadInner::Yoke(Yoke::new_owned(data)))
198+
}
199+
200+
#[doc(hidden)]
201+
#[inline]
202+
pub fn from_static_ref(data: &'static M::Yokeable) -> Self {
203+
Self(DataPayloadInner::Ref(data))
199204
}
200205

201206
/// Convert a DataPayload that was created via [`DataPayload::from_owned()`] back into the
202207
/// concrete type used to construct it.
203208
pub fn try_unwrap_owned(self) -> Result<M::Yokeable, DataError> {
204-
self.yoke
205-
.try_into_yokeable()
206-
.map_err(|_| DataErrorKind::InvalidState.with_str_context("try_unwrap_owned"))
209+
match self.0 {
210+
DataPayloadInner::Yoke(yoke) => yoke.try_into_yokeable().ok(),
211+
DataPayloadInner::Ref(_) => None,
212+
}
213+
.ok_or(DataErrorKind::InvalidState.with_str_context("try_unwrap_owned"))
207214
}
208215

209216
/// Mutate the data contained in this DataPayload.
@@ -244,8 +251,15 @@ where
244251
pub fn with_mut<'a, F>(&'a mut self, f: F)
245252
where
246253
F: 'static + for<'b> FnOnce(&'b mut <M::Yokeable as Yokeable<'a>>::Output),
254+
M::Yokeable: Clone,
247255
{
248-
self.yoke.with_mut(f)
256+
if let DataPayloadInner::Ref(r) = self.0 {
257+
self.0 = DataPayloadInner::Yoke(Yoke::new_owned(M::Yokeable::clone(r)));
258+
}
259+
match &mut self.0 {
260+
DataPayloadInner::Yoke(yoke) => yoke.with_mut(f),
261+
_ => unreachable!(),
262+
}
249263
}
250264

251265
/// Borrows the underlying data.
@@ -266,7 +280,10 @@ where
266280
#[inline]
267281
#[allow(clippy::needless_lifetimes)]
268282
pub fn get<'a>(&'a self) -> &'a <M::Yokeable as Yokeable<'a>>::Output {
269-
self.yoke.get()
283+
match &self.0 {
284+
DataPayloadInner::Yoke(yoke) => yoke.get(),
285+
DataPayloadInner::Ref(r) => Yokeable::transform(*r),
286+
}
270287
}
271288

272289
/// Maps `DataPayload<M>` to `DataPayload<M2>` by projecting it with [`Yoke::map_project`].
@@ -318,10 +335,14 @@ where
318335
<M::Yokeable as Yokeable<'a>>::Output,
319336
PhantomData<&'a ()>,
320337
) -> <M2::Yokeable as Yokeable<'a>>::Output,
338+
M::Yokeable: Clone,
321339
{
322-
DataPayload {
323-
yoke: self.yoke.map_project(f),
324-
}
340+
DataPayload(match self.0 {
341+
DataPayloadInner::Yoke(yoke) => DataPayloadInner::Yoke(yoke.map_project(f)),
342+
DataPayloadInner::Ref(r) => {
343+
DataPayloadInner::Yoke(Yoke::new_owned(r.clone()).map_project(f))
344+
}
345+
})
325346
}
326347

327348
/// Version of [`DataPayload::map_project()`] that borrows `self` instead of moving `self`.
@@ -362,8 +383,16 @@ where
362383
PhantomData<&'a ()>,
363384
) -> <M2::Yokeable as Yokeable<'a>>::Output,
364385
{
365-
DataPayload {
366-
yoke: self.yoke.map_project_cloned(f),
386+
match &self.0 {
387+
DataPayloadInner::Yoke(yoke) => {
388+
DataPayload(DataPayloadInner::Yoke(yoke.map_project_cloned(f)))
389+
}
390+
DataPayloadInner::Ref(r) => {
391+
let output: <M2::Yokeable as Yokeable<'static>>::Output =
392+
f(Yokeable::transform(*r), PhantomData);
393+
let yokeable: M2::Yokeable = unsafe { M2::Yokeable::make(output) };
394+
DataPayload(DataPayloadInner::Yoke(Yoke::new_owned(yokeable)))
395+
}
367396
}
368397
}
369398

@@ -411,10 +440,14 @@ where
411440
<M::Yokeable as Yokeable<'a>>::Output,
412441
PhantomData<&'a ()>,
413442
) -> Result<<M2::Yokeable as Yokeable<'a>>::Output, E>,
443+
M::Yokeable: Clone,
414444
{
415-
Ok(DataPayload {
416-
yoke: self.yoke.try_map_project(f)?,
417-
})
445+
Ok(DataPayload(match self.0 {
446+
DataPayloadInner::Yoke(yoke) => DataPayloadInner::Yoke(yoke.try_map_project(f)?),
447+
DataPayloadInner::Ref(r) => {
448+
DataPayloadInner::Yoke(Yoke::new_owned(r.clone()).try_map_project(f)?)
449+
}
450+
}))
418451
}
419452

420453
/// Version of [`DataPayload::map_project_cloned()`] that bubbles up an error from `f`.
@@ -465,8 +498,16 @@ where
465498
PhantomData<&'a ()>,
466499
) -> Result<<M2::Yokeable as Yokeable<'a>>::Output, E>,
467500
{
468-
Ok(DataPayload {
469-
yoke: self.yoke.try_map_project_cloned(f)?,
501+
Ok(match &self.0 {
502+
DataPayloadInner::Yoke(yoke) => {
503+
DataPayload(DataPayloadInner::Yoke(yoke.try_map_project_cloned(f)?))
504+
}
505+
DataPayloadInner::Ref(r) => {
506+
let output: <M2::Yokeable as Yokeable<'static>>::Output =
507+
f(Yokeable::transform(*r), PhantomData)?;
508+
let yokeable: M2::Yokeable = unsafe { M2::Yokeable::make(output) };
509+
DataPayload(DataPayloadInner::Yoke(Yoke::new_owned(yokeable)))
510+
}
470511
})
471512
}
472513

@@ -497,7 +538,10 @@ where
497538
where
498539
M2: DataMarker<Yokeable = M::Yokeable>,
499540
{
500-
DataPayload { yoke: self.yoke }
541+
DataPayload(match self.0 {
542+
DataPayloadInner::Yoke(yoke) => DataPayloadInner::Yoke(yoke),
543+
DataPayloadInner::Ref(r) => DataPayloadInner::Ref(r),
544+
})
501545
}
502546
}
503547

@@ -507,19 +551,17 @@ impl DataPayload<BufferMarker> {
507551
let yoke = Yoke::attach_to_cart(SelectedRc::new(buffer), |b| &**b);
508552
// Safe because cart is wrapped
509553
let yoke = unsafe { yoke.replace_cart(|b| Some(Cart(b))) };
510-
Self { yoke }
554+
Self(DataPayloadInner::Yoke(yoke))
511555
}
512556

513557
/// Converts a yoked byte buffer into a `DataPayload<BufferMarker>`.
514558
pub fn from_yoked_buffer(yoke: Yoke<&'static [u8], Option<Cart>>) -> Self {
515-
Self { yoke }
559+
Self(DataPayloadInner::Yoke(yoke))
516560
}
517561

518562
/// Converts a static byte buffer into a `DataPayload<BufferMarker>`.
519-
pub fn from_static_buffer(buffer: &'static [u8]) -> Self {
520-
Self {
521-
yoke: Yoke::new_owned(buffer),
522-
}
563+
pub fn from_static_buffer(buffer: &'static &'static [u8]) -> Self {
564+
Self(DataPayloadInner::Ref(buffer))
523565
}
524566
}
525567

provider/datagen/src/baked_exporter.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ struct ImplData {
142142
feature: SyncTokenStream,
143143
macro_ident: SyncTokenStream,
144144
hash_ident: SyncTokenStream,
145+
// These are required for the skeletons special case
146+
into_data_payload: SyncTokenStream,
145147
into_any_payload: SyncTokenStream,
146148
}
147149

@@ -397,10 +399,20 @@ impl DataExporter for BakedExporter {
397399
}
398400
};
399401

400-
let into_any_payload = if is_datetime_skeletons {
402+
let into_data_payload = if is_datetime_skeletons {
401403
quote! {
402404
.map(icu_provider::prelude::zerofrom::ZeroFrom::zero_from)
403405
.map(icu_provider::DataPayload::<#marker>::from_owned)
406+
}
407+
} else {
408+
quote! {
409+
.map(icu_provider::DataPayload::from_static_ref)
410+
}
411+
};
412+
413+
let into_any_payload = if is_datetime_skeletons {
414+
quote! {
415+
#into_data_payload
404416
.map(icu_provider::DataPayload::wrap_into_any_payload)
405417
}
406418
} else {
@@ -416,6 +428,7 @@ impl DataExporter for BakedExporter {
416428
singleton: singleton.map(|t| t.to_string()),
417429
macro_ident: format!("impl_{ident}"),
418430
hash_ident: ident.to_ascii_uppercase(),
431+
into_data_payload: into_data_payload.to_string(),
419432
into_any_payload: into_any_payload.to_string(),
420433
};
421434

@@ -477,6 +490,10 @@ impl DataExporter for BakedExporter {
477490
.values()
478491
.map(|data| data.hash_ident.parse::<TokenStream>().unwrap())
479492
.collect::<Vec<_>>();
493+
let into_data_payloads = data
494+
.values()
495+
.map(|data| data.into_data_payload.parse::<TokenStream>().unwrap())
496+
.collect::<Vec<_>>();
480497
let into_any_payloads = data
481498
.values()
482499
.map(|data| data.into_any_payload.parse::<TokenStream>().unwrap())
@@ -548,8 +565,7 @@ impl DataExporter for BakedExporter {
548565
req: icu_provider::DataRequest,
549566
) -> Result<icu_provider::DataResponse<#markers>, icu_provider::DataError> {
550567
#lookups
551-
.map(icu_provider::prelude::zerofrom::ZeroFrom::zero_from)
552-
.map(icu_provider::DataPayload::from_owned)
568+
#into_data_payloads
553569
.map(|payload| {
554570
icu_provider::DataResponse {
555571
metadata: Default::default(),

provider/testdata/data/baked/macros.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)