Implement derive macro for Pixel

This commit is contained in:
cdo committed 2026-10-26 11:39:45 +00:00
1 parent 689144db8f
commit e75d56e23a
7 files changed
+179 -164

No files matched your search

+46
View File
@@ -0,0 +1,46 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "ccvl_proc_macros"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "ccvl_proc_macros"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
quote = "1.0.47"
syn = "3.0.9"
+68
View File
@@ -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()
}