Serialization with Serde

Serde is Rust's universal serialization framework — derive two traits once and your types convert to and from JSON, TOML, YAML, and many more formats with almost no overhead.

Learn Serialization with Serde in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll derive Serialize and Deserialize, round-trip data through serde_json, customize fields with attributes, handle enums and dynamic JSON, and see how the same code targets other formats.

What You'll Learn in This Lesson

1️⃣ Deriving Serialize and Deserialize

Serde is built on two traits: Serialize turns a value into a format, and Deserialize reads it back. The derive macros generate both. With serde_json , to_string and from_str round-trip your type through JSON.

One derive gave you both directions. Swap serde_json for the toml or serde_yaml crate and the very same type serializes to TOML or YAML.

2️⃣ Customizing Fields with Attributes

Attributes adjust the mapping between Rust and the wire format. rename changes a key, default fills in a missing field, skip drops a field entirely, and a container-level rename_all renames everything at once.

Notice the input had no isActive key, so default supplied false , and the skipped token never appears in the output.

3️⃣ Enums and Dynamic JSON

Enums serialize using a tagged representation; #[serde(tag = "type")] selects an internally tagged form. When you don't have a fixed struct, parse into serde_json::Value — an enum that models any JSON — and index into it.

Use a concrete struct whenever you know the schema; reach for Value only for genuinely dynamic data whose shape isn't known until runtime.

Derive the Serde traits on a small struct and convert it to JSON and back.

📋 Quick Reference — Serde

Practice quiz

What is Serde?

  • A generic serialization and deserialization framework
  • An async runtime
  • A testing library
  • A web server framework

Answer: A generic serialization and deserialization framework. Serde is Rust's de-facto framework for SERializing and DEserializing data structures efficiently and generically.

Which derive macros let a struct convert to and from a data format?

  • Read and Write
  • ToJson and FromJson
  • Serialize and Deserialize
  • Encode and Decode

Answer: Serialize and Deserialize. Adding #[derive(Serialize, Deserialize)] generates the code to convert a type to and from any Serde-supported format.

Which crate provides the JSON data format for Serde?

  • jsonify
  • serde_json
  • json_rs
  • serde_format

Answer: serde_json. serde_json is the official crate implementing the JSON format on top of Serde's core traits.

Which serde_json function turns a value into a JSON string?

  • serde_json::write
  • serde_json::parse
  • serde_json::encode
  • serde_json::to_string

Answer: serde_json::to_string. serde_json::to_string serializes a Serialize value into a JSON String; to_string_pretty adds indentation.

Which serde_json function parses a JSON string into a typed value?

  • serde_json::from_str
  • serde_json::decode
  • serde_json::load
  • serde_json::read

Answer: serde_json::from_str. serde_json::from_str deserializes a JSON string into any type that implements Deserialize.

What does #[serde(rename = "...")] on a field do?

  • Deletes the field
  • Changes the field's serialized key name
  • Marks the field optional
  • Encrypts the value

Answer: Changes the field's serialized key name. The rename attribute maps a Rust field name to a different key in the serialized output and input.

What does #[serde(default)] do when a field is missing during deserialization?

  • Panics
  • Returns an error
  • Skips the whole struct
  • Uses the type's Default value

Answer: Uses the type's Default value. With #[serde(default)], a missing field falls back to Default::default() instead of failing.

What does #[serde(skip)] do to a field?

  • It becomes required
  • It is hashed
  • It is never serialized or deserialized
  • It is renamed

Answer: It is never serialized or deserialized. A field marked #[serde(skip)] is omitted from output and ignored on input, using its default when needed.

What does #[serde(rename_all = "camelCase")] apply to?

  • The whole crate
  • All fields (or variants) at once
  • Only one chosen field
  • Every variant's discriminant only

Answer: All fields (or variants) at once. rename_all on a struct or enum converts every field or variant name to the chosen case convention.

What is serde_json::Value used for?

  • A loosely typed JSON tree when you don't have a fixed struct
  • Speeding up compilation
  • Locking shared data
  • Defining new formats

Answer: A loosely typed JSON tree when you don't have a fixed struct. serde_json::Value is an enum representing arbitrary JSON, useful when the shape isn't known at compile time.