Skip to content

Commit 5c5df51

Browse files
authored
Merge pull request rust-lang#377 from tgross35/shared-function-list
Share a list of all functions between `libm-macros` and `libm-test`
2 parents 83835d0 + a210d4a commit 5c5df51

File tree

6 files changed

+390
-271
lines changed

6 files changed

+390
-271
lines changed

crates/libm-macros/src/enums.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use quote::quote;
55
use syn::spanned::Spanned;
66
use syn::{Fields, ItemEnum, Variant};
77

8-
use crate::{ALL_FUNCTIONS_FLAT, base_name};
8+
use crate::{ALL_OPERATIONS, base_name};
99

1010
/// Implement `#[function_enum]`, see documentation in `lib.rs`.
1111
pub fn function_enum(
@@ -31,15 +31,17 @@ pub fn function_enum(
3131

3232
let enum_name = &item.ident;
3333
let mut as_str_arms = Vec::new();
34+
let mut from_str_arms = Vec::new();
3435
let mut base_arms = Vec::new();
3536

36-
for func in ALL_FUNCTIONS_FLAT.iter() {
37+
for func in ALL_OPERATIONS.iter() {
3738
let fn_name = func.name;
3839
let ident = Ident::new(&fn_name.to_upper_camel_case(), Span::call_site());
3940
let bname_ident = Ident::new(&base_name(fn_name).to_upper_camel_case(), Span::call_site());
4041

4142
// Match arm for `fn as_str(self)` matcher
4243
as_str_arms.push(quote! { Self::#ident => #fn_name });
44+
from_str_arms.push(quote! { #fn_name => Self::#ident });
4345

4446
// Match arm for `fn base_name(self)` matcher
4547
base_arms.push(quote! { Self::#ident => #base_enum::#bname_ident });
@@ -50,24 +52,45 @@ pub fn function_enum(
5052
item.variants.push(variant);
5153
}
5254

55+
let variants = item.variants.iter();
56+
5357
let res = quote! {
5458
// Instantiate the enum
5559
#item
5660

5761
impl #enum_name {
62+
/// All variants of this enum.
63+
pub const ALL: &[Self] = &[
64+
#( Self::#variants, )*
65+
];
66+
5867
/// The stringified version of this function name.
5968
pub const fn as_str(self) -> &'static str {
6069
match self {
6170
#( #as_str_arms , )*
6271
}
6372
}
6473

74+
/// If `s` is the name of a function, return it.
75+
pub fn from_str(s: &str) -> Option<Self> {
76+
let ret = match s {
77+
#( #from_str_arms , )*
78+
_ => return None,
79+
};
80+
Some(ret)
81+
}
82+
6583
/// The base name enum for this function.
6684
pub const fn base_name(self) -> #base_enum {
6785
match self {
6886
#( #base_arms, )*
6987
}
7088
}
89+
90+
/// Return information about this operation.
91+
pub fn math_op(self) -> &'static crate::op::MathOpInfo {
92+
crate::op::ALL_OPERATIONS.iter().find(|op| op.name == self.as_str()).unwrap()
93+
}
7194
}
7295
};
7396

@@ -85,8 +108,7 @@ pub fn base_name_enum(
85108
return Err(syn::Error::new(sp.span(), "no attributes expected"));
86109
}
87110

88-
let mut base_names: Vec<_> =
89-
ALL_FUNCTIONS_FLAT.iter().map(|func| base_name(func.name)).collect();
111+
let mut base_names: Vec<_> = ALL_OPERATIONS.iter().map(|func| base_name(func.name)).collect();
90112
base_names.sort_unstable();
91113
base_names.dedup();
92114

0 commit comments

Comments
 (0)