silk.json.object.
Write a JSON object, one member at a time, to the Writer.
When to use#
Use JsonObject in a Serialize implementation to write a struct as a JSON object. Start
with JsonObject.begin, add members with JsonObject.field or JsonObject.fieldIfSome,
and finish with JsonObject.end, in one |> chain.
Details#
Each step returns an effect that the next step runs, so the chain writes the members in order. The object keeps track of commas and of the depth. It does not allocate.
Errors#
JsonErrorif the nesting is deeper than the limit in the options, or a value fails.WriterErrorif theWriterfails. Bytes that it accepted before the failure stay written.
Examples#
Write a struct as an object#
import silk.core.effect { Effect }
import silk.json.codec { Serialize }
import silk.json.object { JsonObject }
import silk.json.output { JsonOptions }
import silk.json.scanner { JsonError }
import silk.json.value { Json }
import silk.io.writer { Writer, WriterError }
struct CaptureWriter {
bytes: [u8; 64],
length: usize,
}
impl Writer for CaptureWriter {
effect fn writeAll(self: &mut Self, value: &[u8]) -> ()
! WriterError
? &mut Writer {
let mut index: usize = 0
while index < value.length {
self.bytes[self.length] = value[index]
self.length = self.length + 1
index = index + 1
}
return ()
}
effect fn flush(self: &mut Self) -> ()
! WriterError
? &mut Writer {
return ()
}
}
fn holds(writer: &CaptureWriter, expected: &[u8]) -> bool {
if writer.length != expected.length {
return false
}
let mut index: usize = 0
while index < expected.length {
if writer.bytes[index] != expected[index] {
return false
}
index = index + 1
}
return true
}
struct Point {
x: i32,
y: i32,
}
impl Serialize for Point {
effect fn serialize(self: &Self, options: &JsonOptions) -> ()
! JsonError | WriterError
? &mut Writer {
return run JsonObject.begin(options) |> JsonObject.field("x", &self.x)
|> JsonObject.field("y", &self.y)
|> JsonObject.end
}
}
pub effect fn main() -> i32
! JsonError | WriterError {
let mut writer = CaptureWriter { bytes: [0; 64], length: 0 }
let point = Point { x: 3, y: -4 }
run Json.serialize(&point, &JsonOptions.compact()) |> Effect.provideMut<Writer>(&mut writer)
if !holds(&writer, b"{\"x\":3,\"y\":-4}") {
return 1
}
return 0
}Import as JsonObject with import silk.json.object { JsonObject }.
Public declarations: 1.
JsonObject#
pub struct JsonObjectThe state of one open JSON object: its options and if a member was written.
When to use#
Use it in a Serialize implementation to write a struct as a JSON object. Start with
JsonObject.begin, add members with JsonObject.field or JsonObject.fieldIfSome, and
finish with JsonObject.end, in one |> chain.
Details#
Each step returns an effect that the next step runs, so the chain writes the members in order. The object keeps track of commas and of the depth. It does not allocate.
Implementation JsonObject#
impl JsonObjectAssociated function begin#
pub effect fn begin(options: &JsonOptions)
-> JsonObject ! JsonError | WriterError ? &mut WriterWrites { and returns the state of the open object.
Errors#
JsonErrorwith reasonDepthExceededif the object would be deeper than the limit inoptions. Nothing is written.WriterErrorif theWriterfails. Bytes that it accepted before the failure stay written.
Method field#
pub effect fn field<'env, T: Serialize, E, ?R>(
self: once Effect<'env; JsonObject ! E ? R>,
key: string<'env>,
value: &'env T
) -> JsonObject ! E | JsonError | WriterError ? R | &mut WriterWrites the member name with value, after a comma if needed.
Details#
The object operations form a chain with |>: JsonObject.begin(options) |>
JsonObject.field(...) |> JsonObject.end. Each step takes the effect of the step before it and
runs it one time. If an earlier step fails, this step writes nothing.
Errors#
JsonErrorfromvalue.WriterErrorif theWriterfails. Bytes that it accepted before the failure stay written.
Method fieldIfSome#
pub effect fn fieldIfSome<'env, T: Serialize, E, ?R>(
self: once Effect<'env; JsonObject ! E ? R>,
key: string<'env>,
value: &'env Option<T>
) -> JsonObject ! E | JsonError | WriterError ? R | &mut WriterWrites the member name if value is present. Writes nothing for an absent value: no key and
no comma.
When to use#
Use it for optional fields that the JSON leaves out when they are absent. JsonObject.field
with an Option writes null instead.
Details#
The object operations form a chain with |>: JsonObject.begin(options) |>
JsonObject.field(...) |> JsonObject.end. Each step takes the effect of the step before it and
runs it one time. If an earlier step fails, this step writes nothing.
Errors#
JsonErrorfromvalue.WriterErrorif theWriterfails. Bytes that it accepted before the failure stay written.
Method end#
pub effect fn end<'env, E, ?R>(
self: once Effect<'env; JsonObject ! E ? R>
) -> () ! E | JsonError | WriterError ? R | &mut WriterWrites } and completes the object. If the object has members and indentation is on, it
writes a newline first.
Details#
The object operations form a chain with |>: JsonObject.begin(options) |>
JsonObject.field(...) |> JsonObject.end. Each step takes the effect of the step before it and
runs it one time. If an earlier step fails, this step writes nothing.
Errors#
JsonErrorfrom an earlier step.WriterErrorif theWriterfails. Bytes that it accepted before the failure stay written.
Category: Data formats.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.