1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ Copyright: (c) 2023, Mike 'PhiSyX' S. (https://github.com/PhiSyX)         ┃
// ┃ SPDX-License-Identifier: MPL-2.0                                          ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃                                                                           ┃
// ┃  This Source Code Form is subject to the terms of the Mozilla Public      ┃
// ┃  License, v. 2.0. If a copy of the MPL was not distributed with this      ┃
// ┃  file, You can obtain one at https://mozilla.org/MPL/2.0/.                ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

use axum::http;

use crate::ApplicationEnvInterface;

// --------- //
// Structure //
// --------- //

pub struct Env<E>(pub E);

// ----------- //
// Énumération //
// ----------- //

#[derive(Debug)]
#[derive(thiserror::Error)]
pub enum MissingEnvError {
	#[error("\n\t{}: {0}", std::any::type_name::<Self>())]
	Extension(#[from] axum::extract::rejection::ExtensionRejection),
}

// -------------- //
// Implémentation // -> Interface
// -------------- //

#[async_trait::async_trait]
impl<S, C> axum::extract::FromRequestParts<S> for Env<C>
where
	C: 'static,
	C: ApplicationEnvInterface,
	S: Send + Sync,
{
	type Rejection = MissingEnvError;

	async fn from_request_parts(
		parts: &mut axum::http::request::Parts,
		state: &S,
	) -> Result<Self, Self::Rejection> {
		axum::Extension::<C>::from_request_parts(parts, state)
			.await
			.map(|axum::Extension(ext)| Self(ext))
			.map_err(MissingEnvError::Extension)
	}
}

impl axum::response::IntoResponse for MissingEnvError {
	fn into_response(self) -> axum::response::Response {
		let err_status = http::StatusCode::INTERNAL_SERVER_ERROR;
		let err_body = self.to_string();
		(err_status, err_body).into_response()
	}
}