code_status_macros/lib.rs
1//! Code Status Macros
2//!
3//! A collection of procedural macros for annotating code with development status markers
4//! and tracking technical debt. These macros provide a standardized way for teams to mark
5//! and track various development concerns in code.
6//!
7//! # Available Macros
8//!
9//! ## Code Quality Markers
10//!
11//! - [`untested`] - Marks functions that haven't been properly tested
12//! - [`includes_unwrap`] - Indicates code containing unwrap() calls that could panic
13//! - [`needs`] - Indicates a specific need (e.g., refactoring, optimization)
14//! - [`perf_critical`] - Marks code that needs performance optimization
15//! - [`security_sensitive`] - Marks code with known security implications
16//! - [`unsafe_usage`] - Marks code that uses unsafe blocks and needs careful auditing
17//! - [`no_clippy`] - Marks code where certain clippy lints are deliberately suppressed
18//! - [`complexity`] - Indicates high algorithm or cognitive complexity issues
19//! - [`allocation_heavy`] - Flags functions that perform significant heap allocations
20//! - [`panic_path`] - Highlights code paths that might panic under specific conditions
21//!
22//! ## Review & Future Work Markers
23//!
24//! - [`needs_review`] - Indicates code that requires special review before release
25//! - [`temporary`] - Marks code as temporary or intended to be replaced
26//! - [`assumptions`] - Indicates code with non-obvious assumptions
27//! - [`revisit_in`] - Marks code that may need revisiting in a future version
28//! - [`dependency_sensitive`] - Marks code that's sensitive to changes in dependencies
29//! - [`platform_specific`] - Indicates code with behavior tied to specific platforms
30//! - [`feature_gated`] - Marks code dependent on specific feature flags
31//! - [`api_stability`] - Indicates parts of the API that may change
32//! - [`deadlock_risk`] - Marks code with potential concurrency/deadlock issues
33//! - [`benchmark_candidate`] - Flags code that should be benchmarked and optimized
34
35extern crate proc_macro;
36
37use proc_macro::TokenStream;
38use quote::quote;
39use syn::{parse_macro_input, Item, LitStr};
40
41/// A marker attribute to indicate that a function is untested.
42/// This attribute does not modify the function it annotates.
43#[proc_macro_attribute]
44pub fn untested(_attr: TokenStream, item: TokenStream) -> TokenStream {
45 // Parse the input tokens into a syntax tree item (like a function).
46 let item_ast = parse_macro_input!(item as syn::Item);
47
48 // Use quote to reconstruct the token stream for the item.
49 // This effectively returns the original function unchanged.
50 TokenStream::from(quote! { #item_ast })
51}
52
53/// A marker attribute to indicate a specific need for an item (e.g., function).
54/// Accepts a string literal describing the need, like `#[needs("refactoring")]`.
55/// Can be applied multiple times to the same item.
56/// This attribute does not modify the item it annotates.
57#[proc_macro_attribute]
58pub fn needs(attr: TokenStream, item: TokenStream) -> TokenStream {
59 // Parse the attribute argument (the string literal).
60 // We expect a single string literal, e.g., #[needs("some reason")]
61 // We parse it to ensure it's a valid string literal, but don't use the value.
62 let _reason = parse_macro_input!(attr as LitStr);
63
64 // Parse the input tokens into a syntax tree item (like a function).
65 let item_ast = parse_macro_input!(item as Item);
66
67 // Use quote to reconstruct the token stream for the item.
68 // This effectively returns the original item unchanged.
69 TokenStream::from(quote! { #item_ast })
70}
71
72/// A marker attribute to indicate that a function contains `unwrap()` calls.
73/// This helps identify potential panic points in code.
74/// This attribute does not modify the function it annotates.
75#[proc_macro_attribute]
76pub fn includes_unwrap(_attr: TokenStream, item: TokenStream) -> TokenStream {
77 // Parse the input tokens into a syntax tree item (like a function).
78 let item_ast = parse_macro_input!(item as syn::Item);
79
80 // Use quote to reconstruct the token stream for the item.
81 // This effectively returns the original function unchanged.
82 TokenStream::from(quote! { #item_ast })
83}
84
85/// Mark code that needs performance optimization.
86/// This helps identify areas that could be bottlenecks.
87/// This attribute does not modify the item it annotates.
88#[proc_macro_attribute]
89pub fn perf_critical(_attr: TokenStream, item: TokenStream) -> TokenStream {
90 let item_ast = parse_macro_input!(item as syn::Item);
91 TokenStream::from(quote! { #item_ast })
92}
93
94/// Mark code with known security implications.
95/// This helps identify areas that might need security auditing.
96/// This attribute does not modify the item it annotates.
97#[proc_macro_attribute]
98pub fn security_sensitive(_attr: TokenStream, item: TokenStream) -> TokenStream {
99 let item_ast = parse_macro_input!(item as syn::Item);
100 TokenStream::from(quote! { #item_ast })
101}
102
103/// Indicate code that requires special review before release.
104/// This helps identify areas that need careful review by team members.
105/// This attribute does not modify the item it annotates.
106#[proc_macro_attribute]
107pub fn needs_review(_attr: TokenStream, item: TokenStream) -> TokenStream {
108 let item_ast = parse_macro_input!(item as syn::Item);
109 TokenStream::from(quote! { #item_ast })
110}
111
112/// Mark code as temporary or intended to be replaced.
113/// This helps identify code that should not be considered permanent.
114/// This attribute does not modify the item it annotates.
115#[proc_macro_attribute]
116pub fn temporary(_attr: TokenStream, item: TokenStream) -> TokenStream {
117 let item_ast = parse_macro_input!(item as syn::Item);
118 TokenStream::from(quote! { #item_ast })
119}
120
121/// Indicate that code has non-obvious assumptions.
122/// Accepts a string literal describing the assumptions, like `#[assumptions("assumes sorted input")]`.
123/// This attribute does not modify the item it annotates.
124#[proc_macro_attribute]
125pub fn assumptions(attr: TokenStream, item: TokenStream) -> TokenStream {
126 let _description = parse_macro_input!(attr as LitStr);
127 let item_ast = parse_macro_input!(item as Item);
128 TokenStream::from(quote! { #item_ast })
129}
130
131/// Mark code that may need revisiting in a future version.
132/// Accepts a string literal describing when to revisit, like `#[revisit_in("v2.0")]`.
133/// This attribute does not modify the item it annotates.
134#[proc_macro_attribute]
135pub fn revisit_in(attr: TokenStream, item: TokenStream) -> TokenStream {
136 let _version = parse_macro_input!(attr as LitStr);
137 let item_ast = parse_macro_input!(item as Item);
138 TokenStream::from(quote! { #item_ast })
139}
140
141/// Mark code that's sensitive to changes in dependencies.
142/// This helps identify code that might break when dependencies are updated.
143/// This attribute does not modify the item it annotates.
144#[proc_macro_attribute]
145pub fn dependency_sensitive(_attr: TokenStream, item: TokenStream) -> TokenStream {
146 let item_ast = parse_macro_input!(item as syn::Item);
147 TokenStream::from(quote! { #item_ast })
148}
149
150/// Mark code that uses unsafe blocks and needs careful auditing.
151/// Optionally accepts a string literal describing the reason for unsafe usage,
152/// like `#[unsafe_usage("raw pointer arithmetic for performance")]`.
153/// This attribute does not modify the item it annotates.
154#[proc_macro_attribute]
155pub fn unsafe_usage(attr: TokenStream, item: TokenStream) -> TokenStream {
156 let _reason = if !attr.is_empty() {
157 Some(parse_macro_input!(attr as LitStr))
158 } else {
159 None
160 };
161 let item_ast = parse_macro_input!(item as syn::Item);
162 TokenStream::from(quote! { #item_ast })
163}
164
165/// Mark code where certain clippy lints are deliberately suppressed.
166/// Accepts a string literal describing which lints and why,
167/// like `#[no_clippy("too_many_arguments: this API needs to be flexible")]`.
168/// This attribute does not modify the item it annotates.
169#[proc_macro_attribute]
170pub fn no_clippy(attr: TokenStream, item: TokenStream) -> TokenStream {
171 let _description = parse_macro_input!(attr as LitStr);
172 let item_ast = parse_macro_input!(item as Item);
173 TokenStream::from(quote! { #item_ast })
174}
175
176/// Indicate code with behavior tied to specific platforms.
177/// Accepts a string literal describing the platform dependencies,
178/// like `#[platform_specific("windows")]` or `#[platform_specific("linux, macos")]`.
179/// This attribute does not modify the item it annotates.
180#[proc_macro_attribute]
181pub fn platform_specific(attr: TokenStream, item: TokenStream) -> TokenStream {
182 let _platforms = parse_macro_input!(attr as LitStr);
183 let item_ast = parse_macro_input!(item as Item);
184 TokenStream::from(quote! { #item_ast })
185}
186
187/// Mark code dependent on specific feature flags.
188/// Accepts a string literal describing the feature dependency,
189/// like `#[feature_gated("async")]` or `#[feature_gated("extended-api")]`.
190/// This attribute does not modify the item it annotates.
191#[proc_macro_attribute]
192pub fn feature_gated(attr: TokenStream, item: TokenStream) -> TokenStream {
193 let _feature = parse_macro_input!(attr as LitStr);
194 let item_ast = parse_macro_input!(item as Item);
195 TokenStream::from(quote! { #item_ast })
196}
197
198/// Indicate algorithm complexity or cognitive complexity issues.
199/// Accepts a string literal describing the complexity,
200/// like `#[complexity("O(n²)")]` or `#[complexity("high: many nested conditions")]`.
201/// This attribute does not modify the item it annotates.
202#[proc_macro_attribute]
203pub fn complexity(attr: TokenStream, item: TokenStream) -> TokenStream {
204 let _description = parse_macro_input!(attr as LitStr);
205 let item_ast = parse_macro_input!(item as Item);
206 TokenStream::from(quote! { #item_ast })
207}
208
209/// Flag functions that perform significant heap allocations.
210/// Optionally accepts a string literal with additional details,
211/// like `#[allocation_heavy("allocates vectors for each input item")]`.
212/// This attribute does not modify the item it annotates.
213#[proc_macro_attribute]
214pub fn allocation_heavy(attr: TokenStream, item: TokenStream) -> TokenStream {
215 let _details = if !attr.is_empty() {
216 Some(parse_macro_input!(attr as LitStr))
217 } else {
218 None
219 };
220 let item_ast = parse_macro_input!(item as syn::Item);
221 TokenStream::from(quote! { #item_ast })
222}
223
224/// Highlight code paths that might panic under specific conditions.
225/// Accepts a string literal describing the potential panic scenarios,
226/// like `#[panic_path("fails if input is empty")]`.
227/// This attribute does not modify the item it annotates.
228#[proc_macro_attribute]
229pub fn panic_path(attr: TokenStream, item: TokenStream) -> TokenStream {
230 let _scenario = parse_macro_input!(attr as LitStr);
231 let item_ast = parse_macro_input!(item as Item);
232 TokenStream::from(quote! { #item_ast })
233}
234
235/// Indicate parts of the API that may change.
236/// Accepts a string literal describing the stability level,
237/// like `#[api_stability("unstable")]`, `#[api_stability("experimental")]`,
238/// or `#[api_stability("deprecated: use new_function() instead")]`.
239/// This attribute does not modify the item it annotates.
240#[proc_macro_attribute]
241pub fn api_stability(attr: TokenStream, item: TokenStream) -> TokenStream {
242 let _stability = parse_macro_input!(attr as LitStr);
243 let item_ast = parse_macro_input!(item as Item);
244 TokenStream::from(quote! { #item_ast })
245}
246
247/// Mark code with potential concurrency/deadlock issues.
248/// Optionally accepts a string literal detailing the risk,
249/// like `#[deadlock_risk("acquires multiple locks")]`.
250/// This attribute does not modify the item it annotates.
251#[proc_macro_attribute]
252pub fn deadlock_risk(attr: TokenStream, item: TokenStream) -> TokenStream {
253 let _details = if !attr.is_empty() {
254 Some(parse_macro_input!(attr as LitStr))
255 } else {
256 None
257 };
258 let item_ast = parse_macro_input!(item as syn::Item);
259 TokenStream::from(quote! { #item_ast })
260}
261
262/// Flag code that should be benchmarked and optimized.
263/// Optionally accepts a string literal with benchmarking notes,
264/// like `#[benchmark_candidate("bottleneck in processing pipeline")]`.
265/// This attribute does not modify the item it annotates.
266#[proc_macro_attribute]
267pub fn benchmark_candidate(attr: TokenStream, item: TokenStream) -> TokenStream {
268 let _notes = if !attr.is_empty() {
269 Some(parse_macro_input!(attr as LitStr))
270 } else {
271 None
272 };
273 let item_ast = parse_macro_input!(item as syn::Item);
274 TokenStream::from(quote! { #item_ast })
275}