///|
/// Identifies one variant of an enum within the data model.
///
/// Serde passes `(name, variant_index, variant)` positionally to four separate
/// methods; bundling them keeps the `Serializer` signatures readable and makes
/// it impossible to transpose the two names by accident.
pub(all) struct VariantInfo {
/// Name of the enum type, e.g. `"Shape"`.
enum_name : String
/// Zero-based declaration order of the variant.
index : Int
/// Name of the variant itself, e.g. `"Circle"`.
name : String
}
///|
/// A data type that can describe itself to any `Serializer`.
///
/// This is half of serde's central idea: a type knows its own shape in terms of
/// the data model, and a format knows how to write the data model. Neither
/// knows about the other, so N types and M formats cost N + M implementations
/// instead of N * M.
///
/// `serialize` is polymorphic in the serializer, so this trait has no trait
/// object form — exactly as in Rust. Use `Value` when a heterogeneous
/// collection is needed.
pub(open) trait Serialize {
fn[S : Serializer] serialize(Self, S) -> Unit raise SerError
}
///|
/// A format that can receive the data model.
///
/// Serde returns a distinct builder type from `serialize_seq`, `serialize_map`
/// and friends, which statically prevents mixing up two open compounds. MoonBit
/// has no associated types, so the compound protocols are flattened onto `Self`
/// as `_begin` / element / `_end` triples. That makes correct nesting a
/// contract rather than a type guarantee: every `_begin` must be matched by
/// exactly one `_end`, and implementations that nest must track their own depth.
///
/// Many methods have defaults that widen to a more general part of the data
/// model — tuples fall back to sequences, tuple structs to tuples — so a format
/// only overrides the ones it represents distinctly.
pub(open) trait Serializer {
// ---- primitives ----
fn serialize_unit(Self) -> Unit raise SerError
fn serialize_bool(Self, Bool) -> Unit raise SerError
fn serialize_byte(Self, Byte) -> Unit raise SerError
fn serialize_int16(Self, Int16) -> Unit raise SerError
fn serialize_uint16(Self, UInt16) -> Unit raise SerError
fn serialize_int(Self, Int) -> Unit raise SerError
fn serialize_uint(Self, UInt) -> Unit raise SerError
fn serialize_int64(Self, Int64) -> Unit raise SerError
fn serialize_uint64(Self, UInt64) -> Unit raise SerError
fn serialize_float(Self, Float) -> Unit raise SerError
fn serialize_double(Self, Double) -> Unit raise SerError
fn serialize_char(Self, Char) -> Unit raise SerError
fn serialize_string(Self, String) -> Unit raise SerError
fn serialize_bytes(Self, Bytes) -> Unit raise SerError
// ---- option ----
fn serialize_none(Self) -> Unit raise SerError
fn[T : Serialize] serialize_some(Self, T) -> Unit raise SerError
// ---- named units and newtypes ----
/// A struct with no fields, e.g. `struct Marker`. Defaults to unit.
fn serialize_unit_struct(Self, String) -> Unit raise SerError = _
/// A struct wrapping exactly one value, e.g. `struct Meters(Double)`.
/// Defaults to serializing the inner value transparently.
fn[T : Serialize] serialize_newtype_struct(Self, String, T) -> Unit raise SerError = _
fn serialize_unit_variant(Self, VariantInfo) -> Unit raise SerError
fn[T : Serialize] serialize_newtype_variant(Self, VariantInfo, T) -> Unit raise SerError
// ---- sequences: length is a hint, absent when not known up front ----
fn serialize_seq_begin(Self, Int?) -> Unit raise SerError
fn[T : Serialize] serialize_seq_element(Self, T) -> Unit raise SerError
fn serialize_seq_end(Self) -> Unit raise SerError
// ---- tuples: fixed, heterogeneous, length always known ----
fn serialize_tuple_begin(Self, Int) -> Unit raise SerError = _
fn[T : Serialize] serialize_tuple_element(Self, T) -> Unit raise SerError = _
fn serialize_tuple_end(Self) -> Unit raise SerError = _
// ---- tuple structs, e.g. `struct Rgb(Int, Int, Int)` ----
fn serialize_tuple_struct_begin(Self, String, Int) -> Unit raise SerError = _
fn[T : Serialize] serialize_tuple_struct_field(Self, T) -> Unit raise SerError = _
fn serialize_tuple_struct_end(Self) -> Unit raise SerError = _
// ---- maps: keys need not be strings ----
fn serialize_map_begin(Self, Int?) -> Unit raise SerError
fn[K : Serialize] serialize_map_key(Self, K) -> Unit raise SerError
fn[V : Serialize] serialize_map_value(Self, V) -> Unit raise SerError
fn serialize_map_end(Self) -> Unit raise SerError
// ---- structs: like a map, but keys are known statically ----
fn serialize_struct_begin(Self, String, Int) -> Unit raise SerError
fn[T : Serialize] serialize_field(Self, String, T) -> Unit raise SerError
fn serialize_struct_end(Self) -> Unit raise SerError
// ---- enum variants carrying payloads ----
fn serialize_tuple_variant_begin(Self, VariantInfo, Int) -> Unit raise SerError
fn[T : Serialize] serialize_tuple_variant_element(Self, T) -> Unit raise SerError = _
fn serialize_tuple_variant_end(Self) -> Unit raise SerError
fn serialize_struct_variant_begin(Self, VariantInfo, Int) -> Unit raise SerError
fn[T : Serialize] serialize_struct_variant_field(Self, String, T) -> Unit raise SerError = _
fn serialize_struct_variant_end(Self) -> Unit raise SerError
/// Whether the target format is meant to be read by people.
///
/// Types use this to choose between a readable and a compact encoding of the
/// same value — an IP address as `"127.0.0.1"` for JSON, as four bytes for a
/// binary format. Defaults to `true`.
fn is_human_readable(Self) -> Bool = _
}
///|
impl Serializer with fn serialize_unit_struct(self, _name) {
self.serialize_unit()
}
///|
impl Serializer with fn serialize_newtype_struct(self, _name, value) {
value.serialize(self)
}
///|
impl Serializer with fn serialize_tuple_begin(self, len) {
self.serialize_seq_begin(Some(len))
}
///|
impl Serializer with fn serialize_tuple_element(self, value) {
self.serialize_seq_element(value)
}
///|
impl Serializer with fn serialize_tuple_end(self) {
self.serialize_seq_end()
}
///|
impl Serializer with fn serialize_tuple_struct_begin(self, _name, len) {
self.serialize_tuple_begin(len)
}
///|
impl Serializer with fn serialize_tuple_struct_field(self, value) {
self.serialize_tuple_element(value)
}
///|
impl Serializer with fn serialize_tuple_struct_end(self) {
self.serialize_tuple_end()
}
///|
impl Serializer with fn serialize_tuple_variant_element(self, value) {
self.serialize_seq_element(value)
}
///|
impl Serializer with fn serialize_struct_variant_field(self, name, value) {
self.serialize_field(name, value)
}
///|
impl Serializer with fn is_human_readable(_self) {
true
}