redfish_axum/
resource_block_collection.rs

1// Generated by redfish-codegen. Do not modify.
2
3/// The default privileges required for accessing ResourceBlockCollection instances.
4pub struct DefaultPrivileges;
5impl redfish_core::privilege::OperationPrivilegeMapping for DefaultPrivileges {
6    type Get = redfish_core::privilege::Login;
7    type Head = redfish_core::privilege::Login;
8    type Post = redfish_core::privilege::ConfigureComponents;
9    type Put = redfish_core::privilege::ConfigureComponents;
10    type Patch = redfish_core::privilege::ConfigureComponents;
11    type Delete = redfish_core::privilege::ConfigureComponents;
12}
13
14/// This endpoint implements the ResourceBlockCollection component.
15///
16/// It can be mounted on the following components:
17/// * [CompositionService][crate::composition_service::CompositionService]
18/// * [ServiceRoot][crate::service_root::ServiceRoot]
19pub struct ResourceBlockCollection<S, P>
20where
21    S: Clone,
22{
23    router: axum::routing::MethodRouter<S>,
24    privilege_marker: std::marker::PhantomData<fn() -> P>,
25    allowed_methods: Vec<axum::http::method::Method>,
26    members_router: axum::routing::MethodRouter<S>,
27    resource_block: Option<axum::Router<S>>,
28}
29
30impl<S> Default for ResourceBlockCollection<S, DefaultPrivileges>
31where
32    S: Clone,
33{
34    fn default() -> Self {
35        Self {
36            router: Default::default(),
37            privilege_marker: Default::default(),
38            allowed_methods: Vec::new(),
39            members_router: Default::default(),
40            resource_block: Default::default(),
41        }
42    }
43}
44
45impl<S, P> ResourceBlockCollection<S, P>
46where
47    S: AsRef<dyn redfish_core::auth::AuthenticateRequest> + Clone + Send + Sync + 'static,
48    P: redfish_core::privilege::OperationPrivilegeMapping + 'static,
49    <P as redfish_core::privilege::OperationPrivilegeMapping>::Get: Send,
50    <P as redfish_core::privilege::OperationPrivilegeMapping>::Post: Send,
51{
52    pub fn get<H, T>(mut self, handler: H) -> Self
53    where
54        H: axum::handler::Handler<T, S, axum::body::Body>,
55        T: 'static,
56    {
57        let operation = axum::routing::get(
58            |auth: redfish_core::extract::RedfishAuth<P::Get>,
59             axum::extract::State(state): axum::extract::State<S>,
60             mut request: axum::http::Request<axum::body::Body>| async {
61                request.extensions_mut().insert(auth.user);
62                handler.call(request, state).await
63            },
64        );
65        self.router = self.router.get(operation);
66        self.allowed_methods.push(axum::http::method::Method::GET);
67        self
68    }
69
70    pub fn post<H, T>(mut self, handler: H) -> Self
71    where
72        H: axum::handler::Handler<T, S, axum::body::Body>,
73        T: 'static,
74    {
75        let operation = axum::routing::post(
76            |auth: redfish_core::extract::RedfishAuth<P::Post>,
77             axum::extract::State(state): axum::extract::State<S>,
78             mut request: axum::http::Request<axum::body::Body>| async {
79                request.extensions_mut().insert(auth.user);
80                handler.call(request, state).await
81            },
82        );
83        self.members_router = self.members_router.post(operation.clone());
84        self.router = self.router.post(operation);
85        self.allowed_methods.push(axum::http::method::Method::POST);
86        self
87    }
88
89    /// Serves an instance of a [ResourceBlock][crate::resource_block::ResourceBlock].
90    pub fn resource_block(mut self, resource_block: axum::Router<S>) -> Self {
91        self.resource_block = Some(resource_block);
92        self
93    }
94
95    pub fn into_router(self) -> axum::Router<S> {
96        let Self {
97            router,
98            mut allowed_methods,
99            members_router,
100            resource_block,
101            ..
102        } = self;
103        let result = axum::Router::default();
104        let result = match resource_block {
105            Some(router) => result.nest("/:resource_block_id", router),
106            None => result,
107        };
108        let result = result.route(
109            "/Members",
110            members_router.fallback(|| async {
111                (
112                    axum::http::StatusCode::METHOD_NOT_ALLOWED,
113                    axum::Json(redfish_core::error::one_message(redfish_codegen::registries::base::v1_16_0::Base::OperationNotAllowed.into())),
114                )
115            })
116        );
117        allowed_methods.dedup();
118        let allow_header = allowed_methods
119            .into_iter()
120            .map(|method| method.to_string())
121            .reduce(|one, two| one + "," + &two)
122            .unwrap();
123        result.route(
124            "/",
125            router.fallback(|| async {
126                (
127                    axum::http::StatusCode::METHOD_NOT_ALLOWED,
128                    axum::Json(redfish_core::error::one_message(redfish_codegen::registries::base::v1_16_0::Base::OperationNotAllowed.into())),
129                )
130            })
131            .route_layer(axum::middleware::from_fn_with_state(
132                allow_header,
133                |axum::extract::State(allow_header): axum::extract::State<String>,
134                 request: axum::http::Request<axum::body::Body>,
135                 next: axum::middleware::Next<axum::body::Body>| async move {
136                    let apply_allow = matches!(*request.method(), axum::http::Method::GET | axum::http::Method::HEAD);
137                    let mut response = next.run(request).await;
138                    if apply_allow && !response.headers().contains_key(axum::http::header::ALLOW) {
139                        response.headers_mut().insert(
140                            axum::http::header::ALLOW,
141                            axum::http::HeaderValue::from_str(&allow_header).unwrap(),
142                        );
143                    }
144                    response
145                },
146            )),
147        )
148    }
149}