| Crates.io | herolib-derive |
| lib.rs | herolib-derive |
| version | 0.3.13 |
| created_at | 2025-12-18 06:35:38.652334+00 |
| updated_at | 2026-01-24 05:23:32.869144+00 |
| description | Derive macros for herolib (ToSchema, ToHeroScript, FromHeroScript, Otoml, Actor, rpc_method, OpenRPC client) |
| homepage | |
| repository | https://github.com/herolib/herolib_rust |
| max_upload_size | |
| id | 1991814 |
| size | 144,751 |
Derive macros for herolib providing:
ToSchema - Generate JSON Schema from Rust structsToHeroScript - Serialize Rust structs to HeroScript formatFromHeroScript - Deserialize HeroScript into Rust structsOsisObject - Implement OSIS database object trait for type-safe storageActor - Define RPC-capable actors with OpenRPC specification generationRpcMethod - Mark methods as RPC endpoints[dependencies]
herolib-derive = "0.1"
./build.sh
The Actor system provides a standardized approach for building RPC services with automatic code generation.
An Actor is a self-contained unit that:
use herolib_derive::{Actor, ToSchema};
use serde::{Deserialize, Serialize};
/// Input for greeting.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GreetInput {
pub name: String,
}
/// Output after greeting.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct GreetOutput {
pub message: String,
}
/// Greeter handles greeting operations.
#[derive(Actor)]
#[actor(name = "greeter")]
pub struct Greeter;
impl Greeter {
/// Say hello to someone.
#[rpc_method]
#[rpc_example(
input = r#"{ "name": "World" }"#,
output = r#"{ "message": "Hello, World!" }"#
)]
pub async fn hello(
&self,
input: GreetInput,
logger: &RequestLogger,
) -> Result<GreetOutput, ActorError> {
logger.info(format!("Greeting {}", input.name)).await;
Ok(GreetOutput {
message: format!("Hello, {}!", input.name),
})
}
}
For each actor, the macros generate:
| Artifact | Description |
|---|---|
{actor}.openrpc.json |
OpenRPC 1.3 specification |
{actor}_client.rs |
Type-safe async client |
{actor}_handler.rs |
Redis queue handler/server |
{actor}_api.md |
API documentation |
{actor}_api_redis.md |
API documentation with Redis details |
Actors communicate via Redis queues:
actors:{actor_name}:{instance}:queue # Request queue (List)
actors:{actor_name}:{instance}:result:{id} # Results (String)
actors:{actor_name}:{instance}:logs:{id} # Log stream (List)
Client sends request:
LPUSH actors:greeter:main:queue '{"jsonrpc":"2.0","id":"req-1","method":"greeter.hello","params":{"name":"World"}}'
Client reads result:
GET actors:greeter:main:result:req-1
See the docs/ directory for detailed specifications:
Implement the OsisObject trait for type-safe database storage with automatic SmartID generation:
use herolib_derive::OsisObject;
use herolib_osis::sid::SmartId;
use serde::{Serialize, Deserialize};
// Auto-generated type_name: "user"
#[derive(Default, Serialize, Deserialize, OsisObject)]
struct User {
sid: SmartId,
name: String,
}
// Auto-generated type_name: "user_profile"
#[derive(Default, Serialize, Deserialize, OsisObject)]
struct UserProfile {
sid: SmartId,
email: String,
}
// Custom type_name override
#[derive(Default, Serialize, Deserialize, OsisObject)]
#[osis(type_name = "members")]
struct Member {
sid: SmartId,
name: String,
}
Usage with DBTyped:
use herolib_osis::db::DBTyped;
let mut users: DBTyped<User> = DBTyped::new("/data", 0)?;
// Create and store (sid auto-generated)
let mut user = User::default();
user.name = "Alice".into();
users.set(&mut user)?; // user.sid is now set
// Retrieve by SID
let loaded = users.get(&user.sid)?;
Serialize and deserialize Rust structs to/from HeroScript format:
use herolib_derive::{ToHeroScript, FromHeroScript};
#[derive(ToHeroScript, FromHeroScript, Default)]
struct Person {
name: String,
age: u32,
active: bool,
}
// Serialize to HeroScript
let person = Person { name: "John".into(), age: 30, active: true };
let hs = person.to_heroscript("person", "define");
// Output:
// !!person.define
// name:John
// age:30
// active:true
// Deserialize from HeroScript
let script = "!!person.define name:Jane age:25 active:false";
let jane = Person::from_heroscript(script).unwrap();
Generate JSON Schema from Rust types:
use herolib_derive::ToSchema;
#[derive(ToSchema)]
struct Config {
/// Server hostname.
host: String,
/// Server port.
port: u16,
/// Enable debug mode.
#[serde(default)]
debug: bool,
}
// Get JSON Schema
let schema = Config::schema();
Apache-2.0