///|
/// Reads and decodes a required string field from a JSON object.
fn required_string_field(
object : Map[String, Json],
key : String,
label : String,
) -> String raise BootstrapError {
decode_string(required_field(object, key, label), label)
}
///|
/// Reads and decodes a required integer field from a JSON object.
fn required_int_field(
object : Map[String, Json],
key : String,
label : String,
) -> Int raise BootstrapError {
decode_int(required_field(object, key, label), label)
}
///|
/// Returns a required field or a descriptive missing-field error.
fn required_field(
object : Map[String, Json],
key : String,
label : String,
) -> Json raise BootstrapError {
match object.get(key) {
Some(value) => value
None => raise MissingField(path=label)
}
}
///|
/// Returns an optional raw JSON field from an object.
fn optional_field(object : Map[String, Json], key : String) -> Json? {
object.get(key)
}
///|
/// Decodes an optional string field while preserving `None`.
fn decode_optional_string(
json : Json?,
label : String,
) -> String? raise BootstrapError {
match json {
None => None
Some(json) => Some(decode_string(json, label))
}
}
///|
/// Decodes an optional integer field while preserving `None`.
fn decode_optional_int(
json : Json?,
label : String,
) -> Int? raise BootstrapError {
match json {
None => None
Some(json) => Some(decode_int(json, label))
}
}
///|
/// Decodes a JSON value as a string with a labeled error message.
fn decode_string(json : Json, label : String) -> String raise BootstrapError {
@json.from_json(json) catch {
error =>
raise InvalidJson(
context=label,
detail="expected string: " + error.to_string(),
)
}
}
///|
/// Decodes a JSON value as an integer with a labeled error message.
fn decode_int(json : Json, label : String) -> Int raise BootstrapError {
@json.from_json(json) catch {
error =>
raise InvalidJson(
context=label,
detail="expected int: " + error.to_string(),
)
}
}
///|
/// Ensures a JSON value is an object before continuing config decoding.
fn expect_object(
json : Json,
label : String,
) -> Map[String, Json] raise BootstrapError {
match json {
Object(object) => object
_ => raise InvalidField(path=label, expectation="must be an object")
}
}
///|
fn[Value] required_built_field(
object : Map[String, Json],
key : String,
label : String,
build : (Json) -> Value raise BootstrapError,
) -> Value raise BootstrapError {
build(required_field(object, key, label))
}