Skip to content

Commit 1118a6b

Browse files
committed
format generics in Label derive
1 parent a88293c commit 1118a6b

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

crates/bevy_ecs/examples/derive_label.rs

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ fn main() {
1818
GenericLabel::<f64>::One.as_label(),
1919
GenericLabel::<char>::One.as_label(),
2020
);
21+
22+
assert_eq!(format!("{:?}", UnitLabel.as_label()), "UnitLabel");
23+
assert_eq!(format!("{:?}", WeirdLabel(1).as_label()), "WeirdLabel");
24+
assert_eq!(format!("{:?}", WeirdLabel(2).as_label()), "WeirdLabel");
25+
assert_eq!(
26+
format!("{:?}", GenericLabel::<f64>::One.as_label()),
27+
"GenericLabel::One::<f64>"
28+
);
2129
}
2230

2331
#[derive(SystemLabel)]

crates/bevy_ecs/src/schedule/state.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
self as bevy_ecs,
23
schedule::{
34
RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun,
45
SystemSet,
@@ -52,20 +53,9 @@ enum ScheduledOperation<T: StateData> {
5253
Push(T),
5354
}
5455

56+
#[derive(RunCriteriaLabel)]
57+
#[run_criteria_label(ignore_fields)]
5558
struct DriverLabel<T: StateData>(PhantomData<fn() -> T>);
56-
impl<T: StateData> RunCriteriaLabel for DriverLabel<T> {
57-
#[inline]
58-
fn type_id(&self) -> std::any::TypeId {
59-
std::any::TypeId::of::<T>()
60-
}
61-
#[inline]
62-
fn data(&self) -> u64 {
63-
0
64-
}
65-
fn fmt(data: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66-
write!(f, "{}", std::any::type_name::<T>())
67-
}
68-
}
6959

7060
fn driver_label<T: StateData>() -> DriverLabel<T> {
7161
DriverLabel(PhantomData)

crates/bevy_macro_utils/src/lib.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub fn derive_label(
141141
.predicates
142142
.push(syn::parse2(quote! { Self: 'static }).unwrap());
143143

144-
let (data, fmt) = match input.data {
144+
let (data, mut fmt) = match input.data {
145145
syn::Data::Struct(d) => {
146146
// see if the user tried to ignore fields incorrectly
147147
if let Some(attr) = d
@@ -226,6 +226,27 @@ pub fn derive_label(
226226
}
227227
};
228228

229+
// Formatting for generics
230+
let mut ty_args = input.generics.params.iter().filter_map(|p| match p {
231+
syn::GenericParam::Type(ty) => Some({
232+
let ty = &ty.ident;
233+
quote! { ::std::any::type_name::<#ty>() }
234+
}),
235+
_ => None,
236+
});
237+
if let Some(first_arg) = ty_args.next() {
238+
// Note: We're doing this manually instead of using magic `syn` methods,
239+
// because those methods insert ugly whitespace everywhere.
240+
// Those are for codegen, not user-facing formatting.
241+
fmt = quote! {
242+
( #fmt )?;
243+
write!(f, "::<")?;
244+
write!(f, "{}", #first_arg)?;
245+
#( write!(f, ", {}", #ty_args)?; )*
246+
write!(f, ">")
247+
}
248+
}
249+
229250
(quote! {
230251
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
231252
#[inline]

0 commit comments

Comments
 (0)