Skip to content

lizelive/dataclasses

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages