///|
fn check_usage(usage : Usage) -> Unit raise PricingError {
label(usage.customer, "usage.customer")
label(usage.metric, "usage.metric")
label(usage.period, "usage.period")
ignore(natural(usage.quantity, "usage.quantity"))
}
///|
/// Decode one already aggregated usage snapshot, without implicit coercions.
pub fn decode_usage(text : String) -> Usage raise PricingError {
usage_from_json(parse_document(text))
}
///|
fn usage_from_json(value : Json) -> Usage raise PricingError {
let object = fields(
value,
["schema", "customer", "metric", "period", "quantity"],
"usage",
)
expect_value(object, "schema", "jieheng.usage.v1", "usage")
let usage = {
customer: text_value(object["customer"], "usage.customer"),
metric: text_value(object["metric"], "usage.metric"),
period: text_value(object["period"], "usage.period"),
quantity: text_value(object["quantity"], "usage.quantity"),
}
check_usage(usage)
usage
}
///|
/// Validate before encoding; no unknown data can be silently lost.
pub fn encode_usage(usage : Usage) -> String raise PricingError {
check_usage(usage)
usage_json(usage).stringify()
}
///|
fn usage_json(usage : Usage) -> Json {
{
"schema": "jieheng.usage.v1",
"customer": usage.customer,
"metric": usage.metric,
"period": usage.period,
"quantity": usage.quantity,
}
}