swiftide_macros/lib.rs
1// show feature flags in the generated documentation
2// https://doc.rust-lang.org/rustdoc/unstable-features.html#extensions-to-the-doc-attribute
3#![cfg_attr(docsrs, feature(doc_cfg))]
4#![cfg_attr(docsrs, feature(doc_auto_cfg))]
5#![doc(html_logo_url = "https://github.com/bosun-ai/swiftide/raw/master/images/logo.png")]
6
7//! This crate provides macros for generating boilerplate code
8//! for indexing transformers
9use proc_macro::TokenStream;
10
11mod indexing_transformer;
12#[cfg(test)]
13mod test_utils;
14mod tool;
15use indexing_transformer::indexing_transformer_impl;
16use syn::{DeriveInput, ItemFn, ItemStruct, parse_macro_input};
17use tool::{tool_attribute_impl, tool_derive_impl};
18
19/// Generates boilerplate for an indexing transformer.
20#[proc_macro_attribute]
21pub fn indexing_transformer(args: TokenStream, input: TokenStream) -> TokenStream {
22 let input = parse_macro_input!(input as ItemStruct);
23 indexing_transformer_impl(args.into(), input).into()
24}
25
26#[proc_macro_attribute]
27/// Creates a `Tool` from an async function.
28///
29/// # Example
30/// ```ignore
31/// #[tool(description = "Searches code", param(name = "code_query", description = "The code query"))]
32/// pub async fn search_code(context: &dyn AgentContext, code_query: &str) -> Result<ToolOutput,
33/// ToolError> {
34/// Ok("hello".into())
35/// }
36///
37/// // The tool can then be used with agents:
38/// Agent::builder().tools([search_code()])
39///
40/// // Or
41///
42/// Agent::builder().tools([SearchCode::default()])
43/// ```
44pub fn tool(args: TokenStream, input: TokenStream) -> TokenStream {
45 let input = parse_macro_input!(input as ItemFn);
46 tool_attribute_impl(&args.into(), &input).into()
47}
48
49/// Derive `Tool` on a struct.
50///
51/// Useful if your structs have internal state and you want to use it in your tool.
52///
53/// # Example
54/// ```ignore
55/// #[derive(Clone, Tool)]
56/// #[tool(description = "Searches code", param(name = "code_query", description = "The code query"))]
57/// pub struct SearchCode {
58/// search_command: String
59/// }
60///
61/// impl SearchCode {
62/// pub async fn search_code(&self, context: &dyn AgentContext, code_query: &str) -> Result<ToolOutput, ToolError> {
63/// context.exec_cmd(&self.search_command.into()).await.map(Into::into)
64/// }
65/// }
66/// ```
67#[proc_macro_derive(Tool, attributes(tool))]
68pub fn derive_tool(input: TokenStream) -> TokenStream {
69 let input = parse_macro_input!(input as DeriveInput);
70
71 match tool_derive_impl(&input) {
72 Ok(tokens) => tokens.into(),
73 Err(err) => err.into_compile_error().into(),
74 }
75}