Skip to content

Commit

Permalink
refactor(macros): clean up declare_oxc_secret
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Sep 25, 2024
1 parent a4fdf1b commit 3015a91
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 42 deletions.
75 changes: 33 additions & 42 deletions crates/oxc_macros/src/declare_oxc_secret.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
Ident, LitFloat, LitInt, LitStr, Token,
};
use syn::{parse::Parse, Ident, LitFloat, LitInt, LitStr, Token};

use super::declare_oxc_lint::rule_name_converter;
use super::{
declare_oxc_lint::rule_name_converter,
util::{eat_comma, parse_assert},
};

pub struct SecretRuleMeta {
struct_name: Ident,
Expand All @@ -16,12 +16,12 @@ pub struct SecretRuleMeta {
}

impl Parse for SecretRuleMeta {
fn parse(mut input: syn::parse::ParseStream) -> syn::Result<Self> {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let struct_name = input.parse()?;
input.parse::<Token!(,)>()?;
let description = input.parse()?;

eat_comma(&mut input)?;
eat_comma(&input)?;

let mut rule = SecretRuleMeta {
struct_name,
Expand All @@ -33,46 +33,45 @@ impl Parse for SecretRuleMeta {

while input.peek(Ident) {
let ident = input.parse::<Ident>()?;
#[allow(clippy::neg_cmp_op_on_partial_ord)]
match ident.to_string().as_str() {
"entropy" => {
input.parse::<Token!(=)>()?;
let entropy = input.parse::<LitFloat>()?;
if entropy.base10_parse::<f32>()? < 0.0 {
return Err(syn::Error::new_spanned(
entropy,
"Entropy must be greater than or equal to 0.",
));
}
parse_assert!(
entropy.base10_parse::<f32>()? >= 0.0,
entropy,
"Entropy must be greater than or equal to 0."
);
rule.entropy = Some(entropy);
}
"min_len" => {
input.parse::<Token!(=)>()?;
let min_len = input.parse::<LitInt>()?;
if min_len.base10_parse::<u32>()? < 1 {
return Err(syn::Error::new_spanned(
min_len,
"Minimum length cannot be zero.",
));
}
parse_assert!(
min_len.base10_parse::<u32>()? > 0,
min_len,
"Minimum length must be greater than or equal to 1."
);
rule.min_len = Some(min_len);
}
"max_len" => {
input.parse::<Token!(=)>()?;
let max_len = input.parse::<LitInt>()?;
if max_len.base10_parse::<u32>()? < 1 {
return Err(syn::Error::new_spanned(
max_len,
"Maximum length cannot be zero.",
));
}
parse_assert!(
max_len.base10_parse::<u32>()? > 0,
max_len,
"Maximum length cannot be zero."
);
rule.max_len = Some(max_len);
}
_ => return Err(syn::Error::new_spanned(
_ => parse_assert!(
false,
ident,
"Unexpected attribute. Only `entropy`, `min_len`, and `max_len` are allowed",
)),
"Unexpected attribute. Only `entropy`, `min_len`, and `max_len` are allowed."
),
}
eat_comma(&mut input)?;
eat_comma(&input)?;
}

// Ignore the rest
Expand All @@ -81,12 +80,11 @@ impl Parse for SecretRuleMeta {
if let (Some(min), Some(max)) = (rule.min_len.as_ref(), &rule.max_len.as_ref()) {
let min = min.base10_parse::<u32>()?;
let max = max.base10_parse::<u32>()?;
if min > max {
return Err(syn::Error::new_spanned(
max,
"Maximum length must be greater than or equal to minimum length.",
));
}
parse_assert!(
min <= max,
max,
"Maximum length must be greater than or equal to minimum length."
);
}

Ok(rule)
Expand Down Expand Up @@ -155,10 +153,3 @@ pub fn declare_oxc_secret(meta: SecretRuleMeta) -> TokenStream {

TokenStream::from(output)
}

fn eat_comma(input: &mut ParseStream) -> syn::Result<()> {
if input.peek(Token!(,)) {
input.parse::<Token!(,)>()?;
}
Ok(())
}
2 changes: 2 additions & 0 deletions crates/oxc_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use proc_macro::TokenStream;
use syn::parse_macro_input;

#[macro_use]
mod util;
mod declare_all_lint_rules;
mod declare_oxc_lint;
mod declare_oxc_secret;
Expand Down
34 changes: 34 additions & 0 deletions crates/oxc_macros/src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use syn::{parse::ParseStream, Result, Token};

/// Checks if `cond` is `true`, returning [`Err(syn::Error)`] with `msg` if it's not.
/// ## Example
/// ```ignore
/// use syn::{parse::Parse, LitStr};
///
/// struct Foo(LitStr);
///
/// impl Parse for Foo {
/// fn parse(input: ParseStream) -> Result<Self> {
/// let s = input.parse::<LitStr>()?;
/// parse_assert!(s.value() == "foo", s, "Expected 'foo'");
/// Ok(Foo(s))
/// }
/// }
/// ```
macro_rules! parse_assert {
($cond:expr, $toks:expr, $msg:expr) => {
if !($cond) {
return Err(syn::Error::new_spanned($toks, $msg));
}
};
}
pub(crate) use parse_assert;

/// Consume a comma token if it's present, noop otherwise
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn eat_comma(input: &ParseStream) -> Result<()> {
if input.peek(Token!(,)) {
input.parse::<Token!(,)>()?;
}
Ok(())
}

0 comments on commit 3015a91

Please sign in to comment.