Skip to main content

hyperstack_macros/
lib.rs

1//! # hyperstack-macros
2//!
3//! Procedural macros for defining HyperStack streams.
4//!
5//! This crate provides the `#[hyperstack]` attribute macro that transforms
6//! annotated Rust structs into full streaming pipeline specifications, including:
7//!
8//! - State struct generation with field accessors
9//! - Handler creation functions for event processing
10//! - IDL/Proto parser integration for Solana programs
11//! - Automatic AST serialization for deployment
12//!
13//! ## Module Usage (IDL-based)
14//!
15//! ```rust,ignore
16//! use hyperstack_macros::{hyperstack, Stream};
17//!
18//! #[hyperstack(idl = "idl.json")]
19//! pub mod my_stream {
20//!     #[entity(name = "MyEntity")]
21//!     #[derive(Stream)]
22//!     struct Entity {
23//!         #[map(from = "MyAccount", field = "value")]
24//!         pub value: u64,
25//!     }
26//! }
27//! ```
28//!
29//! ## Supported Attributes
30//!
31//! - `#[map(...)]` - Map from account fields
32//! - `#[from_instruction(...)]` - Map from instruction fields
33//! - `#[event(...)]` - Capture instruction events
34//! - `#[snapshot(...)]` - Capture entire source data
35//! - `#[aggregate(...)]` - Aggregate field values
36//! - `#[computed(...)]` - Computed fields from other fields
37//! - `#[derive_from(...)]` - Derive values from instructions
38
39// Public modules - AST types needed for SDK generation
40pub(crate) mod ast;
41pub(crate) mod event_type_helpers;
42
43// Internal modules - not exposed publicly
44mod codegen;
45mod idl_codegen;
46mod idl_parser_gen;
47mod idl_vixen_gen;
48mod parse;
49mod proto_codegen;
50mod stream_spec;
51mod utils;
52
53use proc_macro::TokenStream;
54use std::collections::HashMap;
55use syn::{parse_macro_input, ItemMod, ItemStruct};
56
57// Use the stream_spec module functions
58use stream_spec::{process_module, process_struct_with_context};
59
60/// Process a `#[hyperstack(...)]` attribute.
61///
62/// This macro can be applied to:
63/// - A module containing entity structs
64/// - A single struct (legacy usage)
65///
66/// ## Module Usage (IDL-based)
67///
68/// ```rust,ignore
69/// #[hyperstack(idl = "idl.json")]
70/// pub mod my_stream {
71///     #[entity(name = "MyEntity")]
72///     struct Entity {
73///         // fields with mapping attributes
74///     }
75/// }
76/// ```
77///
78/// ## Proto-based Usage
79///
80/// ```rust,ignore
81/// #[hyperstack(proto = ["events.proto"])]
82/// pub mod my_stream {
83///     // entity structs
84/// }
85/// ```
86#[proc_macro_attribute]
87pub fn hyperstack(attr: TokenStream, item: TokenStream) -> TokenStream {
88    if let Ok(module) = syn::parse::<ItemMod>(item.clone()) {
89        return process_module(module, attr);
90    }
91
92    let input = parse_macro_input!(item as ItemStruct);
93    process_struct_with_context(input, HashMap::new(), false)
94}
95
96/// Derive macro for `Stream`.
97///
98/// This is a marker derive that enables the following attributes on struct fields:
99/// - `#[map(...)]` - Map from account fields
100/// - `#[from_instruction(...)]` - Map from instruction fields
101/// - `#[event(...)]` - Capture instruction events
102/// - `#[snapshot(...)]` - Capture entire source
103/// - `#[aggregate(...)]` - Aggregate field values
104/// - `#[computed(...)]` - Computed fields from other fields
105/// - `#[derive_from(...)]` - Derive values from instructions
106#[proc_macro_derive(
107    Stream,
108    attributes(
109        map,
110        from_instruction,
111        event,
112        snapshot,
113        aggregate,
114        computed,
115        derive_from
116    )
117)]
118pub fn stream_derive(_input: TokenStream) -> TokenStream {
119    TokenStream::new()
120}