hyperactor_config_macros/lib.rs
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9//! Procedural macros for hyperactor_config.
10
11use proc_macro::TokenStream;
12use quote::quote;
13use syn::DeriveInput;
14use syn::parse_macro_input;
15
16/// Derive the [`hyperactor_config::attrs::AttrValue`] trait for a struct or enum.
17///
18/// This macro generates an implementation that uses the type's `ToString` and `FromStr`
19/// implementations for the `display` and `parse` methods respectively.
20///
21/// The type must already implement the required super-traits:
22/// `Named + Sized + Serialize + DeserializeOwned + Send + Sync + Clone + 'static`
23/// as well as `ToString` and `FromStr`.
24///
25/// # Example
26///
27/// ```ignore
28/// #[derive(AttrValue, Named, Serialize, Deserialize, Clone)]
29/// struct MyCustomType {
30/// value: String,
31/// }
32///
33/// impl std::fmt::Display for MyCustomType {
34/// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
35/// write!(f, "{}", self.value)
36/// }
37/// }
38///
39/// impl std::str::FromStr for MyCustomType {
40/// type Err = std::io::Error;
41///
42/// fn from_str(s: &str) -> Result<Self, Self::Err> {
43/// Ok(MyCustomType {
44/// value: s.to_string(),
45/// })
46/// }
47/// }
48/// ```
49#[proc_macro_derive(AttrValue)]
50pub fn derive_attr_value(input: TokenStream) -> TokenStream {
51 let input = parse_macro_input!(input as DeriveInput);
52 let name = &input.ident;
53
54 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
55
56 TokenStream::from(quote! {
57 impl #impl_generics hyperactor_config::attrs::AttrValue for #name #ty_generics #where_clause {
58 fn display(&self) -> String {
59 self.to_string()
60 }
61
62 fn parse(value: &str) -> Result<Self, anyhow::Error> {
63 value.parse().map_err(|e| anyhow::anyhow!("failed to parse {}: {}", stringify!(#name), e))
64 }
65 }
66 })
67}