| Crates.io | dataclass-macro |
| lib.rs | dataclass-macro |
| version | 0.1.0 |
| created_at | 2024-11-14 19:36:00.050248+00 |
| updated_at | 2024-11-14 19:36:00.050248+00 |
| description | A procedural macro for generating dataclasses in Rust. |
| homepage | |
| repository | https://github.com/asukaminato0721/dataclass-macro |
| max_upload_size | |
| id | 1448244 |
| size | 26,257 |
A Rust procedural macro that implements Python-style dataclasses. This macro helps reduce boilerplate code by automatically implementing common traits and generating constructors for your structs.
@dataclass decoratorAdd this to your Cargo.toml:
[dependencies]
dataclass-macro = "0.1.0" # Replace with actual version
Basic usage:
use dataclass_macro::dataclass;
#[dataclass] // Use all default options
struct Point {
x: i32,
y: i32,
}
// With custom options
#[dataclass(
init = true,
repr = true,
eq = true,
order = true,
unsafe_hash = true,
frozen = false,
slots = false
)]
struct Person {
name: String,
age: i32,
email: Option<String>,
}
fn main() {
let person = Person::new(
String::from("Alice"),
30,
Some(String::from("alice@example.com"))
);
println!("{:?}", person); // Debug output thanks to repr=true
let clone = person.clone(); // Clone is always implemented
assert_eq!(person, clone); // PartialEq is implemented when eq=true
}
| Option | Default | Description |
|---|---|---|
init |
true |
Generate a constructor |
repr |
true |
Implement Debug trait |
eq |
true |
Implement PartialEq and Eq traits |
order |
false |
Implement Ord and PartialOrd traits |
unsafe_hash |
false |
Implement Hash trait |
frozen |
false |
Make fields immutable (pub(crate)) |
match_args |
true |
Enable pattern matching support |
kw_only |
false |
Constructor requires named arguments |
slots |
false |
Optimize memory layout |
weakref_slot |
false |
Reserved for future use |
For a basic struct with default options, the macro generates:
// Your code
#[dataclass]
struct Point {
x: i32,
y: i32,
}
// Generated code
#[derive(Clone)]
pub struct Point {
pub x: i32,
pub y: i32,
}
impl Point {
pub fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
}
impl std::fmt::Debug for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Point")
.field("x", &self.x)
.field("y", &self.y)
.finish()
}
}
impl PartialEq for Point {
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y
}
}
impl Eq for Point {}
serde: Enable serde support for serialization/deserialization[dependencies]
dataclass-macro = { version = "0.1.0", features = ["serde"] }
use dataclass_macro::dataclass;
#[dataclass]
struct Point {
x: i32,
y: i32,
}
let point = Point::new(10, 20);
println!("{:?}", point); // Point { x: 10, y: 20 }
#[dataclass(order = true)]
struct Version {
major: u32,
minor: u32,
patch: u32,
}
let v1 = Version::new(1, 0, 0);
let v2 = Version::new(2, 0, 0);
assert!(v1 < v2); // Comparison works
#[dataclass(frozen = true)]
struct Config {
name: String,
value: i32,
}
let config = Config::new(String::from("test"), 42);
// config.value = 43; // This would cause a compilation error
use dataclass_macro::dataclass;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
#[dataclass]
struct User {
#[serde(rename = "userName")]
name: String,
age: i32,
#[serde(skip_serializing_if = "Option::is_none")]
email: Option<String>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let user = User::new(
String::from("Alice"),
30,
Some(String::from("alice@example.com"))
);
// Serialize to JSON
let json = serde_json::to_string_pretty(&user)?;
println!("JSON:\n{}", json);
// Deserialize from JSON
let deserialized: User = serde_json::from_str(&json)?;
assert_eq!(user, deserialized);
Ok(())
}
For more detailed serde integration examples, including custom serialization, working with complex types, and different formats, see SERDE.md.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
This macro aims to provide similar functionality to Python's dataclass decorator while remaining true to Rust's patterns and safety guarantees. The main differences are: