Skip to content

Commit

Permalink
Merge pull request #25 from Cakefish/feature/attribute_forwarding
Browse files Browse the repository at this point in the history
Forward attributes by checking in type_info for always_ref types
  • Loading branch information
IsseW authored Nov 25, 2024
2 parents 7b7e19b + db454da commit 8c782ec
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
31 changes: 30 additions & 1 deletion bauble/src/value/asset_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum OwnedTypeInfo {
module: String,
ident: String,
always_ref: bool,
attributes: Vec<String>,
},
Kind(ValueKind),
Flatten {
Expand Down Expand Up @@ -65,6 +66,7 @@ impl OwnedTypeInfo {
module: module.into(),
ident: ident.into(),
always_ref: false,
attributes: Vec::new(),
}
}
}
Expand All @@ -75,6 +77,7 @@ pub enum TypeInfo<'a> {
module: &'a str,
ident: &'a str,
always_ref: bool,
attributes: &'a [&'a str],
},
Kind(ValueKind),
Flatten {
Expand All @@ -92,15 +95,22 @@ impl<'a> TypeInfo<'a> {
module,
ident,
always_ref: false,
attributes: &[],
}
}

pub const fn with_always_ref(self) -> Self {
match self {
TypeInfo::Path { module, ident, .. } => TypeInfo::Path {
TypeInfo::Path {
module,
ident,
attributes,
..
} => TypeInfo::Path {
module,
ident,
always_ref: true,
attributes,
},
TypeInfo::Flatten {
module,
Expand All @@ -117,16 +127,35 @@ impl<'a> TypeInfo<'a> {
}
}

pub const fn with_attributes(self, attributes: &'a [&'a str]) -> Self {
match self {
TypeInfo::Path {
module,
ident,
always_ref,
..
} => TypeInfo::Path {
module,
ident,
always_ref,
attributes,
},
s => s,
}
}

pub fn to_owned(&self) -> OwnedTypeInfo {
match self {
TypeInfo::Path {
module,
ident,
always_ref,
attributes,
} => OwnedTypeInfo::Path {
module: module.to_string(),
ident: ident.to_string(),
always_ref: *always_ref,
attributes: attributes.iter().map(|s| s.to_string()).collect(),
},
&TypeInfo::Kind(kind) => OwnedTypeInfo::Kind(kind),
TypeInfo::Flatten {
Expand Down
25 changes: 22 additions & 3 deletions bauble/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ impl Value {
}
)
}
pub fn attributes(&self) -> &[String] {
let type_info = match self {
Value::Tuple(Some(type_info), _)
| Value::Struct(Some(type_info), _)
| Value::Enum(type_info, _, _) => type_info,
_ => return &[],
};

match type_info {
OwnedTypeInfo::Path { attributes, .. } => attributes,
_ => &[],
}
}
pub fn kind(&self) -> ValueKind {
match self {
Value::Unit => ValueKind::Unit,
Expand Down Expand Up @@ -500,9 +513,15 @@ pub fn convert_values<C: AssetContext>(
let name = format!("@{auto_value_idx:x}");
let span = val.value.span;

// TODO: Possibly list possible attributes for a type info, and chose which to use for which value.
let attributes =
std::mem::replace(&mut val.attributes, Attributes::default().spanned(span));
let mut kept_attrs = Attributes::default().spanned(span);

for attr in val.value.attributes() {
if let Some(val) = val.attributes.0.remove(attr.as_str()) {
kept_attrs.0.insert(attr.clone().spanned(span), val);
}
}

let attributes = std::mem::replace(&mut val.attributes, kept_attrs);

objects.push(create_object(&path, &name, val));
auto_value_idx += 1;
Expand Down
33 changes: 33 additions & 0 deletions bauble_macro_util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,8 @@ pub fn derive_bauble_derive_input(
None => quote! { module_path!() },
};

let mut field_attributes = Vec::new();

// Generate code to deserialize this type
let (type_info, match_value) = match &ast.data {
Data::Struct(data) => {
Expand All @@ -757,6 +759,18 @@ pub fn derive_bauble_derive_input(
Err(err) => return err,
};

for field in &fields.fields {
if matches!(
field.ty,
FieldTy::Val {
attribute: true,
..
}
) {
field_attributes.push(field.name.to_string());
}
}

let case = derive_struct(
TypeInfo {
ty: quote! { Self },
Expand Down Expand Up @@ -887,6 +901,17 @@ pub fn derive_bauble_derive_input(
Ok(fields) => fields,
Err(err) => return Some((quote! {}, err)),
};
for field in &fields.fields {
if matches!(
field.ty,
FieldTy::Val {
attribute: true,
..
}
) {
field_attributes.push(field.name.to_string());
}
}
let derive = derive_struct(
TypeInfo {
ty: quote! { Self::#ident },
Expand Down Expand Up @@ -1021,6 +1046,14 @@ pub fn derive_bauble_derive_input(
type_info
};

let type_info = if field_attributes.is_empty() {
type_info
} else {
quote! {
(#type_info).with_attributes(&[#(#field_attributes),*])
}
};

// Assemble the implementation
quote! {
#[automatically_derived]
Expand Down

0 comments on commit 8c782ec

Please sign in to comment.