problem_details_mapper/builders/
problemdetails_builder.rs

1use http::{StatusCode, Uri};
2use problem_details::ProblemDetails;
3
4pub struct ProblemDetailsBuilder;
5
6impl ProblemDetailsBuilder {
7    const DEFAULT_NOT_FOUND_DETAIL: &'static str = "The requested resource could not be found on the server.";
8    const DEFAULT_BAD_REQUEST_DETAIL: &'static str = "The request is invalid or malformed.";
9    const DEFAULT_SERVER_ERROR_DETAIL: &'static str = "An unexpected error occurred on the server.";
10
11    const DEFAULT_NOT_FOUND_TITLE: &'static str = "Resource not found";
12    const DEFAULT_BAD_REQUEST_TITLE: &'static str = "Bad Request";
13    const DEFAULT_SERVER_ERROR_TITLE: &'static str = "Internal Server Error";
14
15
16    pub fn build_not_found(detail: Option<impl Into<String>>, rtype: Option<impl Into<String>>) -> ProblemDetails {
17        let detail = match detail {
18            Some(d) => d.into(),
19            None => Self::DEFAULT_NOT_FOUND_DETAIL.to_string()
20        };
21
22
23        ProblemDetailsBuilder::build(
24            StatusCode::NOT_FOUND,
25            Self::DEFAULT_NOT_FOUND_TITLE.to_string(),
26            detail,
27            rtype,
28            None::<String>)
29    }
30
31    pub fn build_bad_request(detail: Option<impl Into<String>>, rtype: Option<impl Into<String>>) -> ProblemDetails {
32        let detail = match detail {
33            Some(d) => d.into(),
34            None => Self::DEFAULT_BAD_REQUEST_DETAIL.to_string()
35        };
36
37
38        ProblemDetailsBuilder::build(
39            StatusCode::BAD_REQUEST,
40            Self::DEFAULT_BAD_REQUEST_TITLE.to_string(),
41            detail,
42            rtype,
43            None::<String>)
44    }
45
46    pub fn build_server_error(detail: Option<impl Into<String>>, rtype: Option<impl Into<String>>) -> ProblemDetails {
47        let detail = match detail {
48            Some(d) => d.into(),
49            None => Self::DEFAULT_SERVER_ERROR_DETAIL.to_string()
50        };
51
52
53        ProblemDetailsBuilder::build(
54            StatusCode::INTERNAL_SERVER_ERROR,
55            Self::DEFAULT_SERVER_ERROR_TITLE.to_string(),
56            detail,
57            rtype,
58            None::<String>)
59    }
60
61    pub fn build(status: StatusCode, title: String, detail: String, rtype: Option<impl Into<String>>, instance: Option<impl Into<String>>) -> ProblemDetails {
62        let mut builder = ProblemDetails::new()
63            .with_status(status)
64            .with_title(title)
65            .with_detail(detail);
66
67        if let Some(t) = rtype {
68            builder = builder.with_type(t.into().parse::<Uri>().unwrap());
69        }
70
71        if let Some(i) = instance {
72            builder = builder.with_instance(i.into().parse::<Uri>().unwrap());
73        }
74
75        return builder;
76    }
77}