.. /index

Expert Rust Design

Expert Rust Design

A distillation of what separates A+ Rust from average implementations, drawn from the Rust API Guidelines, production patterns at OneSignal, RisingWave, and ShakaCode, and architectural analysis of tokio, serde, axum, and bevy. The unifying principle: push invariants from runtime to compile time.

The expert mental model

Experts treat borrow checker errors as design feedback, not obstacles. When the compiler rejects code, it means the data ownership model has a flaw worth fixing — not a puzzle to trick the compiler into accepting with clone() or Rc<RefCell<T>>.

The entire memory model decomposes along two orthogonal axes: ownership (responsibility for cleanup) and access (shared &T or exclusive &mut T). From these two concepts, every rule derives: Send means safe to transfer ownership across threads, Sync means safe to share access, and &T is Send iff T is Sync.

The function signature hierarchy: need to destroy it? Take T. Need to modify it? &mut T. Just reading? &T. Small Copy type? Let Rust copy it. Beginners default to cloning; experts restructure data flow.

Structs own all their data; methods borrow parameters. Storing references in structs (&'a T) cascades lifetime complexity through the codebase. The expert alternative: restructure so the struct owns its data, borrows appear only in function parameters.

Core techniques

The seven compile-time techniques from type-driven-development form the foundation: newtypes, phantom types, typestate, illegal-state elimination, exhaustive matching, sealed-traits, and typestate builders. But A+ design extends beyond individual patterns into API surface design, crate architecture, and knowing when to stop abstracting.

Dimensions of expert design

The deepest insight

The crates that define Rust's ecosystem — serde, tokio, axum, bevy — share architectural DNA: facade crates over modular workspaces, trait-driven extensibility, derive macros for ergonomics, and feature flags for compile-time modularity. The highest-quality Rust code is not the cleverest — it's the code where the type system does the thinking, the compiler does the checking, and the developer does the designing.

The same design philosophy now shapes C++. The modern-cpp-design-patterns catalog — std-expected, overloaded-visit-pattern, cpp26-contracts, cpp26-static-reflection, senders-receivers — is the C++ side of the same convergence: push invariants into the type system, prefer value semantics over inheritance, compose at compile time. Reading both surfaces side-by-side makes the underlying principles visible — neither language is the source, and the discipline is portable.

Not every project gets here

A+ Rust is what the cited crates were built with — and what they take years to reach. Most application code is not crate code, and the borrow-aware allocation hierarchy and concurrency framework on this page assume you have the runway to internalize them. high-level-rust is the deliberate counter-position: trade 10–30% of the perf and most of the design discipline for an onboarding curve approximating C#/F#. It picks Arc<dyn Trait> and generous cloning first, exactly the opposite of the pattern this page describes. Both positions are coherent for the workloads they target — A+ Rust is the right answer when the cost of indirection matters; high-level Rust is the right answer when the cost of the team not shipping matters. Naming the choice keeps the discussion honest.

Linked from

Sources