structural-typing 0.1.1

Type-level field presence tracking for Rust structs, inspired by TypeScript
Documentation

Structural Typing for Rust

Define structs with optional fields, tracked at the type level. Inspired by TypeScript, RDF, and this talk.

Installation

cargo add structural-typing

Example

use structural_typing::{structural, presence::Present};

#[structural]
#[derive(Clone, Debug)]
struct User {
    name: String,
    email: String,
    age: u32,
}

fn main() {
    // Build with some fields
    let user = User::empty()
        .name("Alice".to_owned())
        .email("alice@example.com".to_owned());

    // This compiles - greet() requires name field
    println!("{}", user.greet());

    let user = user.age(30);
    // Now all fields present
}

// Methods that require specific fields
// Note: #[structural] generates a snake_case module (User → user)
impl<F: user::Fields<name = Present>> User<F> {
    fn greet(&self) -> String {
        format!("Hello, {}!", self.name)
    }
}

See examples/ for comprehensive usage including merge, split, serde integration, and more.

Features

  • Type-level field tracking (Present, Optional, Absent)
  • Compile-time enforcement of field requirements
  • Builder pattern with .field() that infers presence from value type
  • Type-safe merge and split
  • Automatic serde support
  • Zero runtime overhead

Status

Experimental. API subject to change.

License

MIT OR Apache-2.0