How serde-rs/serde works
Purpose and workspace
Serde is a Rust serialization/deserialization framework. This Cargo workspace separates stable public traits, the user-facing facade, compile-time derives, and validation. Workspace definition: Cargo.toml.
Public API facade
The serde crate is the normal consumer entry point. It re-exports core APIs and conditionally integrates derive support, while retaining compatibility-oriented code such as 128-bit integer handling. Primary paths: serde/src/lib.rs, serde/src/core, serde/src/integer128.rs.
Format-agnostic serialization contract
serde_core defines the format-independent boundary between Rust data types and external format crates: Serialize drives values into a format-provided Serializer; Deserialize reconstructs values through a format-provided Deserializer and visitors. Implementations for standard Rust types live alongside these contracts. Paths: serde_core/src/ser/mod.rs, serde_core/src/de/mod.rs, serde_core/src/lib.rs.
Value traversal and error boundary
Serialization is controlled by the data type’s Serialize implementation; deserialization is controlled by the format parser plus Serde’s Visitor/seed protocol. Formats own concrete wire representations, parsers, output buffers, and error types; Serde owns generic structural traversal and trait contracts. In-memory deserialization utilities and ignored-value support are provided in: serde_core/src/de/value.rs, serde_core/src/de/ignored_any.rs, serde_core/src/ser/impls.rs.
Derive macro compiler pipeline
serde_derive is a procedural-macro crate invoked by Rust compilation for #[derive(Serialize, Deserialize)]. It parses a struct/enum and Serde attributes into an internal AST, validates representation and attribute constraints, computes generic bounds/names, then emits trait implementations for serialization and deserialization. Entry and stages: serde_derive/src/lib.rs, serde_derive/src/internals/ast.rs, serde_derive/src/internals/check.rs.
Generated implementation strategies
Macro generation has distinct serializer and deserializer pipelines. Deserialization generation branches by container shape and enum representation—external, internal, adjacent, and untagged tags—while serialization emits corresponding structural calls into Serializer. Paths: serde_derive/src/ser.rs, serde_derive/src/de.rs, serde_derive/src/de/enum_.rs.
Runtime, integration, and delivery
This is a Rust library workspace, not an application or service. Consumer applications supply data-format crates (for example serde_json); those external crates implement Serde’s serializer/deserializer interfaces. The repository targets standard Rust and constrained/no-std environments, with a no-std integration target at test_suite/no_std/Cargo.toml. GitHub Actions provides CI: .github/workflows/ci.yml.
Main entry points: src/lib.rs serde_core · src/lib.rs serde facade · Cargo.toml Cargo workspace · src/lib.rs serde_derive
Components 19
Workspace
- Cargo workspace · Separates facade, stable contracts, and procedural macros.
Cargo.toml - serde facade · Normal consumer entry point and API re-export layer.
serde/src/lib.rs - 128-bit compatibility
serde/src/integer128.rs
Runtime contracts
- serde_core · Format-independent serialization and deserialization traits.
serde_core/src/lib.rs - Serialize + Serializer · Values drive structural writes into format-owned serializers.
serde_core/src/ser/mod.rs - Deserialize + Deserializer · Format parsers drive reconstruction through visitors and seeds.
serde_core/src/de/mod.rs - Standard type impls
serde_core/src/ser/impls.rs - In-memory values
serde_core/src/de/value.rs - Ignored-value support
serde_core/src/de/ignored_any.rs
Derive compiler
- serde_derive · Invoked by Rust compilation for Serialize and Deserialize derives.
serde_derive/src/lib.rs - Attribute AST · Parses structs, enums, and Serde attributes.
serde_derive/src/internals/ast.rs - Representation checks · Validates attributes and representation constraints.
serde_derive/src/internals/check.rs - Serialize codegen · Emits structural calls into Serializer.
serde_derive/src/ser.rs - Deserialize codegen · Generates container and enum deserialization strategies.
serde_derive/src/de.rs - Enum decoding · Handles external, internal, adjacent, and untagged representations.
serde_derive/src/de/enum_.rs
Integration
- External format crates · Own wire formats, parsers, buffers, and concrete error types.
- Consumer data types · Use Serde traits directly or through generated implementations.
- no-std integration
test_suite/no_std/Cargo.toml - GitHub Actions CI
.github/workflows/ci.yml
Connections 25
- Cargo workspace → serde facade: includes
- Cargo workspace → serde_core: includes
- Cargo workspace → serde_derive: includes
- serde facade → serde_core: re-exports core API
- serde facade → 128-bit compatibility: retains
- serde facade → serde_derive: optional derive integration
- serde_core → Serialize + Serializer: defines
- serde_core → Deserialize + Deserializer: defines
- serde_core → Standard type impls: provides
- serde_core → In-memory values: provides
- serde_core → Ignored-value support: provides
- serde_derive → Attribute AST: parses into
- Attribute AST → Representation checks: validated by
- Representation checks → Serialize codegen: feeds
- Representation checks → Deserialize codegen: feeds
- Deserialize codegen → Enum decoding: branches for enums
- Serialize codegen → Serialize + Serializer: emits impls for
- Deserialize codegen → Deserialize + Deserializer: emits impls for
- Consumer data types → serde_derive: derive invocation
- Consumer data types → Serialize + Serializer: implements or calls
- Consumer data types → Deserialize + Deserializer: implements or calls
- External format crates → Serialize + Serializer: implements serializer
- External format crates → Deserialize + Deserializer: implements deserializer
- no-std integration → serde facade: validates constrained runtime
- GitHub Actions CI → Cargo workspace: builds and validates