| Crates.io | orz |
| lib.rs | orz |
| version | 1.0.0 |
| created_at | 2023-02-01 02:03:00.165089+00 |
| updated_at | 2025-09-30 07:02:58.307745+00 |
| description | A procedural macro for generating field information methods for structs. |
| homepage | |
| repository | |
| max_upload_size | |
| id | 773170 |
| size | 16,860 |
A powerful and practical Rust procedural macro for automatically generating field information methods for structs. The name "Orz" expresses admiration while hinting at the library's powerful capabilities.
Add this to your Cargo.toml:
[dependencies]
orz = "0.1.0"
use orz::Orz;
#[derive(Orz)]
struct User {
#[name("Username")]
username: String,
#[name("Age")]
age: u32,
#[skip]
password_hash: String,
}
let user = User {
username: "alice".to_string(),
age: 30,
password_hash: "hashed".to_string(),
};
println!("Field names: {:?}", User::field_names());
// Output: ["Username", "Age"]
println!("Field values: {:?}", user.field_values());
// Output: ["alice", "30"]
use orz::Orz;
// Custom formatting functions
fn format_count(n: &i32) -> String {
format!("{} items", n)
}
fn format_price(p: &f64) -> String {
format!("¥{:.2}", p)
}
#[derive(Orz, Debug)]
struct Product {
#[name("Product Name")]
name: String,
#[name("Price")]
#[to_string_with("format_price")]
price: f64,
#[name("Stock Quantity")]
#[to_string_with("format_count")]
stock: i32,
#[skip]
secret_info: String,
// No name attribute, uses field name "description"
description: String,
#[name("Debug Info")]
#[debug]
debug_data: Vec<String>,
}
fn main() {
let product = Product {
name: "Laptop".to_string(),
price: 5999.99,
stock: 100,
secret_info: "Confidential".to_string(),
description: "High-performance gaming laptop".to_string(),
debug_data: vec!["data1".to_string(), "data2".to_string()],
};
// Get field names
println!("Field names: {:?}", Product::field_names());
// Output: ["Product Name", "Price", "Stock Quantity", "description", "Debug Info"]
// Get field values
println!("Field values: {:?}", product.field_values());
// Output: ["Laptop", "¥5999.99", "100 items", "High-performance gaming laptop", "[\"data1\", \"data2\"]"]
// Get field count
println!("Field count: {}", Product::field_count());
// Output: 5
// Get detailed field information
for (name, value) in product.field_info() {
println!("{}: {}", name, value);
}
// Output:
// Product Name: Laptop
// Price: ¥5999.99
// Stock Quantity: 100 items
// description: High-performance gaming laptop
// Debug Info: ["data1", "data2"]
}
#[name("Display Name")]Sets the display name for a field. If not set, the field identifier is used by default.
#[name("Username")]
username: String,
#[name("Email Address")]
email: String,
#[skip]Skips the field, excluding it from all outputs.
#[skip]
password_hash: String,
#[skip]
internal_id: u64,
#[to_string_with("function_name")]Uses a custom function to format the field value. Function signature should be fn(&T) -> String.
fn format_date(d: &chrono::NaiveDate) -> String {
d.format("%Y-%m-%d").to_string()
}
#[to_string_with("format_date")]
created_at: chrono::NaiveDate,
#[debug]Formats the field value using the Debug trait ({:?}).
#[debug]
metadata: HashMap<String, String>,
#[debug]
options: Vec<String>,
field_names() -> Vec<&'static str>Returns display names of all fields.
let names = Product::field_names();
// ["Product Name", "Price", "Stock Quantity", "description", "Debug Info"]
field_values(&self) -> Vec<String>Returns string representations of all field values.
let values = product.field_values();
// ["Laptop", "¥5999.99", "100 items", "High-performance gaming laptop", "[\"data1\", \"data2\"]"]
field_info(&self) -> Vec<(&'static str, String)>Returns a mapping of field names to field values.
let info = product.field_info();
// [("Product Name", "Laptop"), ("Price", "¥5999.99"), ...]
field_count() -> usizeReturns the number of fields.
let count = Product::field_count();
// 5
field_values_ref(&self) -> Vec<&str> (Conditionally Generated)Automatically generated when all field types implement AsRef<str> (like &str, String), returning references to field values.
#[derive(Orz)]
struct Log<'a> {
level: &'a str,
message: &'a str,
}
let log = Log { level: "INFO", message: "Hello" };
let refs = log.field_values_ref();
// ["INFO", "Hello"]
Field value formatting priority (highest to lowest):
#[to_string_with("function_name")] - Custom function#[debug] - Debug trait formattingto_string() - Display trait formattingOrz is often used online to express admiration or kneeling in respect. The library name reflects its powerful capabilities:
Using the Orz procedural macro, you'll be impressed by its convenience!
#[name("value")] and #[to_string_with("function_name")] formats# Run example
cargo run --example demo
# Run tests
cargo test
Contributions are welcome! Please feel free to submit pull requests or open issues for any bugs or feature requests.
This project is licensed under the MIT License - see the LICENSE file for details.
Orz - Making struct field reflection in Rust effortless! 🦀