agentic_tools_macros/lib.rs
1//! Proc macros for the agentic-tools library family.
2//!
3//! This crate provides:
4//! - `#[tool]` attribute macro for defining tools
5//! - `#[derive(TextFormat)]` for implementing the TextFormat trait
6
7mod text_format;
8mod tool;
9
10use proc_macro::TokenStream;
11
12/// Attribute macro to define a tool from an async function.
13///
14/// # Usage
15///
16/// ```ignore
17/// use agentic_tools_macros::tool;
18/// use agentic_tools_core::ToolError;
19///
20/// #[tool(name = "my_tool", description = "Does something useful")]
21/// async fn my_tool(input: MyInput) -> Result<MyOutput, ToolError> {
22/// // implementation
23/// }
24/// ```
25///
26/// This generates a `MyToolTool` struct implementing the `Tool` trait.
27///
28/// # Attributes
29///
30/// - `name`: The tool's unique name (defaults to function name)
31/// - `description`: Human-readable description of what the tool does
32#[proc_macro_attribute]
33pub fn tool(attr: TokenStream, item: TokenStream) -> TokenStream {
34 tool::expand(attr.into(), item.into())
35 .unwrap_or_else(|e| e.to_compile_error())
36 .into()
37}
38
39/// Derive macro for implementing the TextFormat trait.
40///
41/// By default, produces pretty-printed JSON. When `markdown = true` in TextOptions,
42/// wraps the JSON in a fenced code block.
43///
44/// # Usage
45///
46/// ```ignore
47/// use agentic_tools_macros::TextFormat;
48///
49/// #[derive(TextFormat, serde::Serialize)]
50/// struct MyOutput {
51/// message: String,
52/// count: usize,
53/// }
54/// ```
55///
56/// # Attributes
57///
58/// - `#[text_format(with = "path::to_fn")]`: Delegate formatting to a custom function.
59/// The function must have signature `fn(&Self, &TextOptions) -> String`.
60///
61/// ```ignore
62/// fn format_my_output(output: &MyOutput, opts: &TextOptions) -> String {
63/// format!("Message: {} (count: {})", output.message, output.count)
64/// }
65///
66/// #[derive(TextFormat, serde::Serialize)]
67/// #[text_format(with = "format_my_output")]
68/// struct MyOutput {
69/// message: String,
70/// count: usize,
71/// }
72/// ```
73#[proc_macro_derive(TextFormat, attributes(text_format))]
74pub fn derive_text_format(input: TokenStream) -> TokenStream {
75 text_format::expand(input.into())
76 .unwrap_or_else(|e| e.to_compile_error())
77 .into()
78}