Why does serde_json use CompactFormatter?

/// This structure compacts a JSON value with no extra whitespace.
#[derive(Clone, Debug)]
pub struct CompactFormatter;

impl Formatter for CompactFormatter {}

/// This structure pretty prints a JSON value to make it human readable.
#[derive(Clone, Debug)]
pub struct PrettyFormatter<'a> {
    current_indent: usize,
    has_value: bool,
    indent: &'a [u8],

Why don't make them in a enum, instead of spliting into 2 structs?

This makes it easier for the compiler to optimize away the pretty formatting algorithm for programs that only use compact, and vice versa. It also saves a lot of runtime checks to decide which formatting algorithm to use: Assuming that serialization is implemented recursively, every JSON subexpression would need to branch on the enum variant separately.

I don't quite get it, would you mind being more specific?

If your program never instantiates a PrettyFormatter, then the compiler knows that it can leave out any function that takes a PrettyFormatter from the final binary. That analysis is much more difficult with an enum because the type system can’t tell the difference between the two variants.

1 Like

The fundamental question of enums vs traits ultimately boils down to design and usage.

You'd presumably not want to dynamically change and/or mix different kinds of formatting, just like you wouldn't – hopefully – mix JSON and XML in your HTTP API, for example.

Therefore, the two formatters don't need to "live together", and they don't in fact have anything to do with each other. Thus, it's appropriate to model them as separate types implementing the same trait.

Furthermore, generics make the code extensible. If you wanted to, you could implement your own formatter and pass it to a serde_json::Deserializer. You can't add variants to someone else's enum.

1 Like

Thanks for explaining, I am actually try to build my own serde crate just like serde_json, it's netconf data type but I am really a newbie to rust, so I started from copying serde_json:)