///|
/// Mutable fluent builder. Build returns a structured error on invalid state.
pub struct ProblemBuilder {
mut type_raw : String?
mut title : String?
mut status : Int?
mut detail : String?
mut instance : String?
extensions : Array[ExtensionMember]
mut error : ProblemError?
}
///|
pub fn ProblemBuilder::new() -> ProblemBuilder {
{
type_raw: None,
title: None,
status: None,
detail: None,
instance: None,
extensions: [],
error: None,
}
}
///|
pub fn ProblemBuilder::type_uri(
self : ProblemBuilder,
value : String,
) -> ProblemBuilder {
self.type_raw = Some(value)
self
}
///|
pub fn ProblemBuilder::title(
self : ProblemBuilder,
value : String,
) -> ProblemBuilder {
self.title = Some(value)
self
}
///|
pub fn ProblemBuilder::status(
self : ProblemBuilder,
value : Int,
) -> ProblemBuilder {
self.status = Some(value)
self
}
///|
pub fn ProblemBuilder::detail(
self : ProblemBuilder,
value : String,
) -> ProblemBuilder {
self.detail = Some(value)
self
}
///|
pub fn ProblemBuilder::instance(
self : ProblemBuilder,
value : String,
) -> ProblemBuilder {
self.instance = Some(value)
self
}
///|
pub fn ProblemBuilder::extension(
self : ProblemBuilder,
name : String,
value : Json,
) -> ProblemBuilder {
if is_reserved_member(name) {
self.error = Some(
problem_error(
Builder,
DuplicateReservedExtension,
"extension collides with reserved member: \{name}",
),
)
} else {
let mut replaced = false
for i = 0; i < self.extensions.length(); i = i + 1 {
if self.extensions[i].name() == name {
self.extensions[i] = extension_member(name, value)
replaced = true
}
}
if !replaced {
self.extensions.push(extension_member(name, value))
}
}
self
}
///|
pub fn ProblemBuilder::build(
self : ProblemBuilder,
) -> Result[ProblemDetails, ProblemError] {
match self.error {
Some(error) => Err(error)
None => {
let value = problem_details(
self.type_raw,
self.title,
self.status,
self.detail,
self.instance,
self.extensions.copy(),
)
let issues = validate_problem(value)
if issues.is_empty() {
Ok(value)
} else {
Err(problem_error(Builder, InvalidBuilderState, issues[0].context()))
}
}
}
}
///|
pub fn problem(
status : Int,
title : String,
) -> Result[ProblemDetails, ProblemError] {
ProblemBuilder::new().status(status).title(title).build()
}
///|
pub fn about_blank(status : Int) -> Result[ProblemDetails, ProblemError] {
let builder = ProblemBuilder::new().status(status)
match status_reason(status) {
Some(reason) => builder.title(reason).build()
None => builder.build()
}
}