///|
/// Mutable object builder retaining each key's original insertion position.
///
/// ```mbt check
/// test {
/// let builder = @json.ObjBuilder::new()
/// .field("name", "sample")
/// .opt("count", (None : Int?))
/// .presence("note", (@json.Null : @json.Presence[String]))
/// assert_eq(builder.build(), { "name": "sample", "note": null })
/// }
/// ```
pub struct ObjBuilder {
priv fields : Map[String, Json]
}
///|
/// Creates an empty builder.
pub fn ObjBuilder::new() -> ObjBuilder {
{ fields: {}, }
}
///|
/// Writes a field, replacing any previous value at its original position.
pub fn[T : ToJson] ObjBuilder::field(
self : ObjBuilder,
key : String,
value : T,
) -> ObjBuilder {
self.fields[key] = value.to_json()
self
}
///|
/// Writes Some values and leaves the builder unchanged for None.
pub fn[T : ToJson] ObjBuilder::opt(
self : ObjBuilder,
key : String,
value : T?,
) -> ObjBuilder {
if value is Some(value) {
self.fields[key] = value.to_json()
}
self
}
///|
/// Omits Absent, writes null for Null, and encodes Value.
pub fn[T : ToJson] ObjBuilder::presence(
self : ObjBuilder,
key : String,
value : Presence[T],
) -> ObjBuilder {
match value {
Absent => ()
Null => self.fields[key] = Json::null()
Value(value) => self.fields[key] = value.to_json()
}
self
}
///|
/// Returns a snapshot of the current fields, preserving insertion order.
pub fn ObjBuilder::build(self : ObjBuilder) -> Json {
Json::object(self.fields.copy())
}