rust 32 lines · 6 steps

Tagged enums with serde in Rust

A single enum models several JSON event shapes using serde's internally tagged representation.

Explained by highlit
1use serde::{Deserialize, Serialize};
2 
3#[derive(Debug, Serialize, Deserialize)]
4#[serde(tag = "type", rename_all = "snake_case")]
5pub enum Event {
6 PageView {
7 url: String,
8 #[serde(default)]
9 referrer: Option<String>,
10 },
11 Click {
12 url: String,
13 element_id: String,
14 #[serde(default)]
15 x: u32,
16 #[serde(default)]
17 y: u32,
18 },
19 FormSubmit {
20 form_id: String,
21 fields: std::collections::HashMap<String, String>,
22 },
23 Custom {
24 name: String,
25 #[serde(default)]
26 payload: serde_json::Value,
27 },
28}
29 
30pub fn parse_events(raw: &str) -> Result<Vec<Event>, serde_json::Error> {
31 serde_json::from_str(raw)
32}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1An internally tagged enum lets one type round-trip several distinct JSON shapes selected by a discriminator field.
  2. 2serde attributes like default and rename_all shape the wire format without changing your Rust field names.
  3. 3Deserializing directly into a domain enum turns runtime JSON validation into compile-time exhaustiveness.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Tagged enums with serde in Rust — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code