Skip to main content

zerodds_web/
status.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! `ReturnStatus` + HTTP-Status-Mapping — Spec §7.3 + §8.3.2.
5
6/// Spec §7.3 — `ReturnStatus`-Codes.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum ReturnStatus {
9    /// `OK` — context-dependent HTTP-Status (siehe `http_status_for`).
10    Ok,
11    /// `OBJECT_ALREADY_EXISTS` → `409 Conflict`.
12    ObjectAlreadyExists,
13    /// `INVALID_INPUT` → `422 Unprocessable Entity`.
14    InvalidInput,
15    /// `INVALID_OBJECT` → `404 Not Found`.
16    InvalidObject,
17    /// `ACCESS_DENIED` → `401 Unauthorized`.
18    AccessDenied,
19    /// `PERMISSIONS_ERROR` → `403 Forbidden`.
20    PermissionsError,
21    /// `GENERIC_SERVICE_ERROR` → `500 Internal Server Error`.
22    GenericServiceError,
23    /// `DDS_ERROR` → `500 Internal Server Error`.
24    DdsError,
25}
26
27/// Spec §8.3.2 + Tab in §8.3 — HTTP-Status-Code-Mapping.
28///
29/// `Ok` haengt vom HTTP-Method ab:
30/// * POST (create) → 201 Created.
31/// * DELETE → 204 No Content.
32/// * GET → 200 OK.
33/// * PUT (update) → 204 No Content.
34#[must_use]
35pub const fn http_status_for(status: ReturnStatus, method: crate::rest::RestMethod) -> u16 {
36    use crate::rest::RestMethod;
37    match status {
38        ReturnStatus::Ok => match method {
39            RestMethod::Post => 201,
40            RestMethod::Delete | RestMethod::Put => 204,
41            RestMethod::Get | RestMethod::Head => 200,
42        },
43        ReturnStatus::ObjectAlreadyExists => 409,
44        ReturnStatus::InvalidInput => 422,
45        ReturnStatus::InvalidObject => 404,
46        ReturnStatus::AccessDenied => 401,
47        ReturnStatus::PermissionsError => 403,
48        ReturnStatus::GenericServiceError | ReturnStatus::DdsError => 500,
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::rest::RestMethod;
56
57    #[test]
58    fn ok_maps_to_201_for_post_create() {
59        // Spec §8.3.2 — Create operations → 201 Created.
60        assert_eq!(http_status_for(ReturnStatus::Ok, RestMethod::Post), 201);
61    }
62
63    #[test]
64    fn ok_maps_to_204_for_delete() {
65        // Spec — DELETE → 204 No Content.
66        assert_eq!(http_status_for(ReturnStatus::Ok, RestMethod::Delete), 204);
67    }
68
69    #[test]
70    fn ok_maps_to_200_for_get() {
71        assert_eq!(http_status_for(ReturnStatus::Ok, RestMethod::Get), 200);
72    }
73
74    #[test]
75    fn ok_maps_to_204_for_put_update() {
76        // Spec — PUT update → 204 No Content.
77        assert_eq!(http_status_for(ReturnStatus::Ok, RestMethod::Put), 204);
78    }
79
80    #[test]
81    fn object_already_exists_maps_to_409() {
82        // Spec.
83        assert_eq!(
84            http_status_for(ReturnStatus::ObjectAlreadyExists, RestMethod::Post),
85            409
86        );
87    }
88
89    #[test]
90    fn invalid_input_maps_to_422() {
91        // Spec — RFC 4918 422 Unprocessable Entity.
92        assert_eq!(
93            http_status_for(ReturnStatus::InvalidInput, RestMethod::Post),
94            422
95        );
96    }
97
98    #[test]
99    fn invalid_object_maps_to_404() {
100        assert_eq!(
101            http_status_for(ReturnStatus::InvalidObject, RestMethod::Get),
102            404
103        );
104    }
105
106    #[test]
107    fn access_denied_maps_to_401() {
108        assert_eq!(
109            http_status_for(ReturnStatus::AccessDenied, RestMethod::Get),
110            401
111        );
112    }
113
114    #[test]
115    fn permissions_error_maps_to_403() {
116        assert_eq!(
117            http_status_for(ReturnStatus::PermissionsError, RestMethod::Post),
118            403
119        );
120    }
121
122    #[test]
123    fn generic_service_error_maps_to_500() {
124        assert_eq!(
125            http_status_for(ReturnStatus::GenericServiceError, RestMethod::Get),
126            500
127        );
128    }
129
130    #[test]
131    fn dds_error_maps_to_500() {
132        assert_eq!(
133            http_status_for(ReturnStatus::DdsError, RestMethod::Post),
134            500
135        );
136    }
137}