Use `specta_serde::format_phases` for split serialization/deserialization shapes
mainThe specta_serde::format_phases implementation handles cases where the wire format differs between serialization and deserialization.
How it works:
- It generates two distinct types:
TypeName_SerializeandTypeName_Deserialize. - It generates a base
TypeNamewhich is a union of the two:TypeName_Serialize | TypeName_Deserialize.
When to use:
- When using directional Serde metadata like
serialize_with,deserialize_with,from,into, ortry_from. - When using the
#[specta(type = specta_serde::Phased<SerializeTy, DeserializeTy>)]override. - Note: You should always prefer
format_phasesoverformatwhenever possible to ensure type accuracy.
use serde::{Deserialize, Serialize};
use serde_with::{OneOrMany, serde_as};
use specta::{Type, Types};
use specta_typescript::Typescript;
#[derive(Type, Serialize, Deserialize)]
#[serde(untagged)]
enum OneOrManyString {
One(String),
Many(Vec<String>),
}
#[serde_as]
#[derive(Type, Serialize, Deserialize)]
struct Filters {
#[serde_as(as = "OneOrMany<_>")]
#[specta(type = specta_serde::Phased<Vec<String>, OneOrManyString>)]
tags: Vec<String>,
}
let types = Types::default().register::<Filters>();
let output = Typescript::default()
.export(&types, specta_serde::format_phases)
.unwrap();
assert!(output.contains("Filters_Serialize"));
assert!(output.contains("Filters_Deserialize"));
assert!(output.contains("OneOrManyString"));