dataclasses

Crates.iodataclasses
lib.rsdataclasses
version0.1.0
created_at2025-11-14 22:08:34.060581+00
updated_at2025-11-14 22:08:34.060581+00
descriptionA small, pragmatic procedural macro providing a Dataclass-like derive for Rust
homepagehttps://github.com/lizelive/dataclasses
repositoryhttps://github.com/lizelive/dataclasses
max_upload_size
id1933544
size29,866
(lizelive)

documentation

README

dataclasses - dataclass-like derive macro for Rust

A small, pragmatic #[derive(Dataclass)] procedural macro inspired by Python's dataclasses module. It generates common boilerplate for struct types, including constructors, Debug, Clone, PartialEq, Eq, and optional Default when all fields provide defaults.

This crate is intended for developers who like the ergonomics of Python dataclasses and want a lightweight, expressive Rust macro that handles common patterns. It's not an exhaustive reimplementation of Python dataclasses, but a carefully chosen set of features that map well to Rust idioms.

Features

  • Generate pub fn new(...) -> Self for named fields, with required fields first and fields with defaults omitted from the constructor
  • Per-field defaults via attribute syntax:
    • #[dataclass(default)] - uses Default::default() for that field
    • #[dataclass(default = "Expr")] - uses the provided Rust expression string as the default (e.g., #[dataclass(default = "Vec::new()")])
  • Derive and implement Clone, Debug, PartialEq and Eq automatically for the struct
  • Implement Default when every field has a default provided
  • Works with generic structs (adds trait bounds as needed for the generated impls)

Quick start

Add this crate as a dependency in your Cargo.toml and enable the proc-macro server if needed. This crate is a proc-macro, so import the derive attribute method like other derive macros.

Example usage:

use dataclasses::Dataclass;

#[derive(Dataclass)]
struct Person {
    name: String,
    age: i32,
    #[dataclass(default)]
    nickname: Option<String>,
    #[dataclass(default = "Vec::new()")]
    tags: Vec<String>,
}

let person = Person::new("Alice".to_string(), 30);
assert_eq!(person.nickname, None);
assert_eq!(person.tags.len(), 0);

When all fields provide defaults, the crate generates a Default impl too:

#[derive(Dataclass)]
struct Defaults {
    #[dataclass(default = "1")]
    a: i32,
    #[dataclass(default)]
    b: String,
}

let d: Defaults = Default::default();
assert_eq!(d.a, 1);

Attributes

  • #[dataclass(default)] - Use Default::default() for this field
  • #[dataclass(default = "Expr")] - Use the provided Expr (a string literal) as the default

Notes:

  • Use double-quoted expressions for default if the expression contains commas or spaces - the parser expects a single string for the expression.
  • Only named struct fields are supported at present.

Limitations and planned improvements

  • Field-level fine-grained control flags like eq=false, skip for Debug/PartialEq, init=False, and repr are not yet available
  • post_init hooks and frozen immutability are not implemented
  • The default = "Expr" currently requires a string literal for the expression; future work could parse expressions directly
  • Trait bound generation is conservative - we add typical bounds for generics when deriving traits; for finer control you can manually implement traits

If you want additional features, please open an issue or a PR.

License

This crate is dual-licensed under MIT or Apache-2.0. You can select either license when using or distributing this crate.

Files: LICENSE-MIT and LICENSE-APACHE are included in this repository.

Commit count: 0

cargo fmt