Implement derive macro for Pixel
This commit is contained in:
1 parent
689144db8f
commit
e75d56e23a
7 files changed
+179
-164
No files matched your search
@@ -0,0 +1,68 @@
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_derive(Pixel)]
|
||||
pub fn pixel_derive(input: TokenStream) -> TokenStream {
|
||||
let ast: syn::DeriveInput =
|
||||
syn::parse(input).expect("Invalid structure declaration");
|
||||
|
||||
if let syn::Data::Struct(def) = ast.data {
|
||||
if let syn::Fields::Named(fields) = def.fields {
|
||||
let names =
|
||||
fields.named.into_iter().map(|field| field.ident.unwrap());
|
||||
impl_pixel(ast.ident, names.collect())
|
||||
} else {
|
||||
panic!("Can only derive Pixel for named fields")
|
||||
}
|
||||
} else {
|
||||
panic!("Can only derive Pixel for a struct")
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_pixel(name: syn::Ident, fields: Vec<syn::Ident>) -> TokenStream {
|
||||
quote::quote! {
|
||||
impl std::ops::AddAssign for #name {
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
#( self.#fields += other.#fields; )*
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::MulAssign<f32> for #name {
|
||||
fn mul_assign(&mut self, scalar: f32) {
|
||||
#( self.#fields *= scalar; )*
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DivAssign<f32> for #name {
|
||||
fn div_assign(&mut self, scalar: f32) {
|
||||
#( self.#fields /= scalar; )*
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<f32> for #name {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(mut self, scalar: f32) -> Self {
|
||||
self *= scalar;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Div<f32> for #name {
|
||||
type Output = Self;
|
||||
|
||||
fn div(mut self, scalar: f32) -> Self {
|
||||
self /= scalar;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for #name {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
#( #fields: Default::default(), )*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Reference in new issue
Block a user