# pulse-schema-derive
Rust proc-macro attributes for generating [Pulse Schema Language (PSL)](https://github.com/Sansa-Organisation/pulse) from native Rust types.
## Overview
Write your schemas as standard Rust structs, enums, and traits — the proc macros emit canonical `.psl` files at compile time, giving you type-safe schema definitions verified by the Rust compiler.
## Quick Start
Add to your `Cargo.toml`:
```toml
[dependencies]
pulse-schema-derive = "0.1"
```
Define your schema:
```rust
use pulse_schema_derive::{pulse_type, pulse_enum, pulse_error, pulse_service, collection, auth};
#[pulse_type]
#[collection]
struct User {
id: String,
name: String,
age: i32,
preferences: Vec<String>,
avatar: Vec<u8>,
is_active: bool,
optional_bio: Option<String>,
}
#[pulse_enum]
enum Role {
Admin,
Moderator,
User,
}
#[pulse_error]
enum ProfileError {
NotFound { id: String },
ValidationFailed { message: String },
}
#[pulse_service]
trait UserService {
#[auth("bearer")]
fn create_user(name: String, age: i32) -> Result<User, ProfileError>;
}
```
Running `cargo build` generates a `schema.psl` file:
```psl
@collection
message User {
id: string;
name: string;
age: int;
preferences: string[];
avatar: bytes;
is_active: boolean;
optional_bio: string?;
}
enum Role {
Admin,
Moderator,
User,
}
error ProfileError {
NotFound {
id: string;
},
ValidationFailed {
message: string;
},
}
service UserService {
@auth("bearer")
rpc create_user(name: string, age: int) -> User ! ProfileError;
}
```
## Type Mappings
| `String` | `string` |
| `i32`, `i64`, `u32`, `u64` | `int` |
| `f32`, `f64` | `float` |
| `bool` | `boolean` |
| `Vec<u8>` | `bytes` |
| `Vec<T>` | `T[]` |
| `Option<T>` | `T?` |
| `HashMap<K, V>` | `map<K, V>` |
| `Result<T, E>` | `-> T ! E` (in services) |
## Attributes
| `#[pulse_type]` | struct | `message Name { ... }` |
| `#[pulse_enum]` | enum | `enum Name { ... }` |
| `#[pulse_error]` | enum | `error Name { ... }` |
| `#[pulse_service]` | trait | `service Name { ... }` |
| `#[collection]` | struct | `@collection` |
| `#[auth("...")]` | fn | `@auth("...")` |
## Cross-Format Compatibility
This crate produces identical PSL output to the TypeScript DSL (`@pulse/schema`). Both are on-ramps to native PSL — the canonical format used for codegen, validation, and database mapping.
## License
MIT