Skip to content

Commit a210d4a

Browse files
committed
Add ALL, from_str and math_op to Identifier
Introduce new API to iterate the function list and associate items with their `MathOp`.
1 parent 6e101af commit a210d4a

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

crates/libm-macros/src/enums.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ 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

3637
for func in ALL_OPERATIONS.iter() {
@@ -40,6 +41,7 @@ pub fn function_enum(
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

crates/libm-macros/tests/enum.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
#[libm_macros::function_enum(BaseName)]
22
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3-
pub enum Function {}
3+
pub enum Identifier {}
44

55
#[libm_macros::base_name_enum]
66
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
77
pub enum BaseName {}
88

99
#[test]
1010
fn as_str() {
11-
assert_eq!(Function::Sin.as_str(), "sin");
12-
assert_eq!(Function::Sinf.as_str(), "sinf");
11+
assert_eq!(Identifier::Sin.as_str(), "sin");
12+
assert_eq!(Identifier::Sinf.as_str(), "sinf");
13+
}
14+
15+
#[test]
16+
fn from_str() {
17+
assert_eq!(Identifier::from_str("sin").unwrap(), Identifier::Sin);
18+
assert_eq!(Identifier::from_str("sinf").unwrap(), Identifier::Sinf);
1319
}
1420

1521
#[test]
1622
fn basename() {
17-
assert_eq!(Function::Sin.base_name(), BaseName::Sin);
18-
assert_eq!(Function::Sinf.base_name(), BaseName::Sin);
23+
assert_eq!(Identifier::Sin.base_name(), BaseName::Sin);
24+
assert_eq!(Identifier::Sinf.base_name(), BaseName::Sin);
1925
}
26+
27+
#[test]
28+
fn math_op() {
29+
assert_eq!(Identifier::Sin.math_op().float_ty, FloatTy::F64);
30+
assert_eq!(Identifier::Sinf.math_op().float_ty, FloatTy::F32);
31+
}
32+
33+
// Replicate the structure that we have in `libm-test`
34+
mod op {
35+
include!("../../libm-macros/src/shared.rs");
36+
}
37+
38+
use op::FloatTy;

0 commit comments

Comments
 (0)