hashira/routing/
error_router.rs1use crate::{components::AnyComponent, app::ErrorPageHandler};
2use http::StatusCode;
3use std::collections::HashMap;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7#[error("failed to insert error page for `{0}`, it already exists")]
8pub struct ErrorPageConflictError(StatusCode);
9
10#[derive(Default, Clone, PartialEq)]
12pub struct ErrorRouter {
13 routes: HashMap<StatusCode, AnyComponent<serde_json::Value>>,
14 fallback: Option<AnyComponent<serde_json::Value>>,
15}
16
17impl ErrorRouter {
18 pub fn new() -> Self {
20 ErrorRouter {
21 routes: HashMap::new(),
22 fallback: None,
23 }
24 }
25
26 pub fn insert(
28 &mut self,
29 status: StatusCode,
30 component: AnyComponent<serde_json::Value>,
31 ) -> Result<(), ErrorPageConflictError> {
32 if self.routes.insert(status, component).is_some() {
33 return Err(ErrorPageConflictError(status));
34 }
35
36 Ok(())
37 }
38
39 pub fn fallback(&mut self, component: AnyComponent<serde_json::Value>) {
41 self.fallback = Some(component);
42 }
43
44 pub fn find(&self, status: &StatusCode) -> Option<&AnyComponent<serde_json::Value>> {
46 self.routes.get(status).or(self.fallback.as_ref())
47 }
48}
49
50#[derive(Default)]
52pub struct ServerErrorRouter {
53 routes: HashMap<StatusCode, ErrorPageHandler>,
54 fallback: Option<ErrorPageHandler>,
55}
56
57impl ServerErrorRouter {
58 pub fn new() -> Self {
60 ServerErrorRouter {
61 routes: HashMap::new(),
62 fallback: None,
63 }
64 }
65
66 pub fn insert(
68 &mut self,
69 status: StatusCode,
70 handler: ErrorPageHandler,
71 ) -> Result<(), ErrorPageConflictError> {
72 if self.routes.insert(status, handler).is_some() {
73 return Err(ErrorPageConflictError(status));
74 }
75
76 Ok(())
77 }
78
79 pub fn fallback(&mut self, handler: ErrorPageHandler) {
81 self.fallback = Some(handler);
82 }
83
84 pub fn find(&self, status: &StatusCode) -> Option<&ErrorPageHandler> {
86 match self.routes.get(status) {
87 Some(handler) => Some(handler),
88 None => self.fallback.as_ref(),
89 }
90 }
91}