Initial commit
This commit is contained in:
Generated
+46
@@ -0,0 +1,46 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bounded_macro"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "bounded_macro"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.46"
|
||||
syn = { version = "2.0.118", features = ["full"] }
|
||||
@@ -0,0 +1,81 @@
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn bounded_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let ast: (syn::MetaList, syn::ItemImpl) = (
|
||||
syn::parse(attr).expect("Attr"),
|
||||
syn::parse(item).expect("Item"),
|
||||
);
|
||||
impl_bounded_macro(&ast.0, &ast.1)
|
||||
}
|
||||
|
||||
fn impl_bounded_macro(attr: &syn::MetaList, item: &syn::ItemImpl) -> TokenStream {
|
||||
let picked_max = item.items.iter()
|
||||
.map_while(|x| {
|
||||
if let syn::ImplItem::Const(x) = x {
|
||||
return Some(x);
|
||||
}
|
||||
None
|
||||
})
|
||||
.find(|x| {
|
||||
x.attrs.iter().any(|x| {
|
||||
x.meta.require_path_only().map_or(false, |x| {
|
||||
x.get_ident().map_or(false, |x| {
|
||||
x == "max"
|
||||
})
|
||||
})
|
||||
})
|
||||
}).expect("");
|
||||
let picked_min = item.items.iter()
|
||||
.map_while(|x| {
|
||||
if let syn::ImplItem::Const(x) = x {
|
||||
return Some(x);
|
||||
}
|
||||
None
|
||||
})
|
||||
.find(|x| {
|
||||
x.attrs.iter().any(|x| {
|
||||
x.meta.require_path_only().map_or(false, |x| {
|
||||
x.get_ident().map_or(false, |x| {
|
||||
x == "min"
|
||||
})
|
||||
})
|
||||
})
|
||||
}).expect("");
|
||||
|
||||
let syn::Expr::Lit(max) = &picked_max.expr else {
|
||||
panic!()
|
||||
};
|
||||
let syn::Expr::Lit(min) = &picked_min.expr else {
|
||||
panic!()
|
||||
};
|
||||
let name = match item.self_ty.as_ref() {
|
||||
syn::Type::Path(p) => p,
|
||||
_ => panic!()
|
||||
};
|
||||
quote::quote! {
|
||||
impl Add<Self> for #name {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self {
|
||||
degree: clip_range(self.degree + rhs.degree, #max, #min),
|
||||
minute: self.minute + rhs.minute,
|
||||
second: self.second + rhs.second,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<i64> for #name {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: i64) -> Self {
|
||||
Self {
|
||||
degree: clip_range(rhs * self.degree, Self::DEGREE_MAX, Self::DEGREE_MIN),
|
||||
minute: clip_range(rhs * self.minute, Self::MINUTE_MAX, Self::MINUTE_MIN),
|
||||
second: clip_range(rhs * self.second, Self::SECOND_MAX, Self::SECOND_MIN),
|
||||
}
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
Reference in New Issue
Block a user