rightkit_daemon/contract/
status.rs1use crate::error::*;
2use crate::ServiceError;
3
4pub const STATUS_TABLE: &[(&str, u16)] = &[
7 ("bad_request", 400),
8 (ERROR_UNAUTHENTICATED, 401),
9 (ERROR_FORBIDDEN, 403),
10 (ERROR_NOT_ALLOWED, 403),
11 (ERROR_REVISION_CONFLICT, 409),
12 (ERROR_RESPONSE_TOO_LARGE, 502),
13 (ERROR_CONNECTION_CLOSED, 502),
14 (ERROR_HOST_HANDOFF, 503),
15 (ERROR_UNAVAILABLE, 503),
16 (ERROR_TIMEOUT, 504),
17 (ERROR_HOST_IDENTITY, 502),
18 (ERROR_SUITE_UNRESOLVED, 500),
19];
20
21pub fn status_for_code(code: &str) -> Option<u16> {
23 STATUS_TABLE
24 .iter()
25 .find(|(c, _)| *c == code)
26 .map(|(_, s)| *s)
27}
28
29pub fn status_for_error(e: &ServiceError) -> u16 {
31 status_for_code(&e.code).unwrap_or(if e.retryable { 503 } else { 500 })
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn known_codes_map_and_unknown_fall_back() {
40 assert_eq!(status_for_code("unauthenticated"), Some(401));
41 assert_eq!(status_for_code("forbidden"), Some(403));
42 assert_eq!(status_for_code("revision_conflict"), Some(409));
43 assert_eq!(status_for_code(ERROR_NOT_ALLOWED), Some(403));
44 assert_eq!(status_for_code("nope"), None);
45 assert_eq!(status_for_error(&ServiceError::new("nope", "x")), 500);
46 assert_eq!(status_for_error(&ServiceError::retryable("nope", "x")), 503);
47 assert_eq!(status_for_error(&ServiceError::handoff()), 503);
48 }
49
50 #[test]
51 fn codes_are_unique() {
52 let mut seen = std::collections::BTreeSet::new();
53 for (c, _) in STATUS_TABLE {
54 assert!(seen.insert(*c), "duplicate {c}");
55 }
56 }
57}