# plexus-macros
Procedural macros for Plexus RPC activations.
## What is Plexus RPC?
Plexus RPC is a protocol for building services with runtime schema introspection. Unlike traditional RPC systems that require separate schema definitions, Plexus RPC extracts schemas directly from your code at runtime. This ensures zero drift between your implementation and schema.
This crate provides macros to generate Plexus RPC-compatible activations from Rust code.
## Overview
The `#[hub_methods]` macro transforms a standard Rust impl block into a fully-functional Plexus RPC activation. It automatically:
- Extracts method schemas from function signatures
- Generates method dispatch logic
- Implements the `Activation` trait for registry integration
- Creates schema introspection endpoints
Your function signature **is** the schema - no separate IDL files needed.
## Quick Start
```rust
use hub_macro::hub_methods;
use serde::{Deserialize, Serialize};
use schemars::JsonSchema;
use futures::stream::Stream;
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ExecuteRequest {
pub command: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum BashEvent {
Stdout { data: String },
Stderr { data: String },
Exit { code: i32 },
}
pub struct Bash {
// your state
}
#[hub_methods(namespace = "bash", version = "1.0.0")]
impl Bash {
/// Execute a bash command and stream output
#[hub_method]
async fn execute(&self, req: ExecuteRequest) -> impl Stream<Item = BashEvent> + Send + 'static {
// implementation
futures::stream::empty()
}
}
```
This generates:
- Method enum for schema extraction
- Activation trait implementation
- RPC server trait and dispatcher
- Schema introspection for `{backend}.schema` calls
## Macro Attributes
### `#[hub_methods]` - Impl Block Level
Marks an impl block as containing Plexus RPC methods.
**Required:**
- `namespace = "..."` - The activation namespace (e.g., "bash", "arbor")
**Optional:**
- `version = "..."` - Semantic version (default: "1.0.0")
- `description = "..."` - Human-readable description
- `crate_path = "..."` - Path to substrate crate (default: "crate")
### `#[hub_method]` - Method Level
Marks an individual method as a Plexus RPC endpoint.
**Features:**
- Extracts method name from function name
- Extracts description from doc comments (`///`)
- Generates input schema from parameter types
- Generates output schema from return type
**Requirements:**
- Method must be `async`
- Must return `impl Stream<Item = YourEvent> + Send + 'static`
- Input type must implement `Deserialize` and `JsonSchema`
- Output event type must implement `Serialize` and `JsonSchema`
## Method Signature Rules
1. **Self parameter:** Can be `&self`, `&mut self`, or no self at all
2. **Input parameter:** First non-self parameter becomes the input schema
3. **Context parameters:** Parameters named `ctx` or `context` are skipped
4. **Return type:** Must be `impl Stream<Item = EventType>`
Example patterns:
```rust
// No input
#[hub_method]
async fn status(&self) -> impl Stream<Item = Status> { ... }
// With input
#[hub_method]
async fn execute(&self, req: Request) -> impl Stream<Item = Event> { ... }
// With context injection
#[hub_method]
async fn process(&self, ctx: &Context, req: Request) -> impl Stream<Item = Event> { ... }
```
## Additional Macros
### `#[derive(HandleEnum)]`
Generates type-safe handle creation and parsing for activation resources.
```rust
use hub_macro::HandleEnum;
use uuid::Uuid;
pub const ARBOR_PLUGIN_ID: Uuid = uuid::uuid!("550e8400-e29b-41d4-a716-446655440000");
#[derive(HandleEnum)]
#[handle(plugin_id = "ARBOR_PLUGIN_ID", version = "1.0.0")]
pub enum ArborHandle {
#[handle(method = "tree")]
Tree { tree_id: String },
#[handle(method = "node")]
Node { tree_id: String, node_id: String },
}
```
This generates:
- `to_handle(&self) -> Handle` - converts enum to Handle
- `impl TryFrom<&Handle>` - parses Handle back to enum
- `impl From<EnumName> for Handle` - convenience conversion
## Schema Introspection
Methods generated by `#[hub_methods]` are automatically discoverable via Plexus RPC's schema introspection:
```bash
# Using the synapse CLI
synapse bash {backend}.schema
```
This returns the complete schema for all methods, extracted from your Rust types.
## Integration with Plexus RPC Ecosystem
This crate is part of the Plexus RPC ecosystem:
- **hub-core** - Core `Activation` trait and `DynamicHub` registry
- **hub-macro** - This crate - procedural macros for activations
- **hub-transport** - WebSocket and HTTP/SSE transport implementations
- **synapse** - CLI for interacting with Plexus RPC servers
- **substrate** - Reference Plexus RPC server implementation
## Examples
See the [substrate](../substrate) reference server for complete examples:
- `bash/` - Shell command execution
- `arbor/` - Conversation tree storage
- `cone/` - LLM orchestration
## License
MIT