Initial commit

This commit is contained in:
2026-07-09 12:58:47 +08:00
commit f5a6403e72
48 changed files with 8174 additions and 0 deletions
+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 = "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"
+11
View File
@@ -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"] }
+81
View File
@@ -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()
}