nova_boot_graphdb/
extractors.rs1use axum::extract::FromRequestParts;
2use axum::http::StatusCode;
3use axum::http::request::Parts;
4use axum::response::{IntoResponse, Response};
5use std::fmt;
6
7#[derive(Clone)]
11pub struct NovaGraph(pub crate::NovaGraphDb);
12
13impl std::fmt::Debug for NovaGraph {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 f.debug_tuple("NovaGraph").field(&"<graph>").finish()
16 }
17}
18
19impl<S> FromRequestParts<S> for NovaGraph
20where
21 S: Send + Sync,
22{
23 type Rejection = NovaGraphRejection;
24
25 fn from_request_parts(
26 parts: &mut Parts,
27 _state: &S,
28 ) -> impl std::future::Future<Output = Result<Self, Self::Rejection>> + Send {
29 let result = parts
30 .extensions
31 .get::<crate::NovaGraphDb>()
32 .cloned()
33 .map(NovaGraph)
34 .ok_or(NovaGraphRejection);
35
36 async move { result }
37 }
38}
39
40#[derive(Debug)]
41pub struct NovaGraphRejection;
42
43impl fmt::Display for NovaGraphRejection {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(
46 f,
47 "Graph database not found in request extensions. Did you forget to add the NovaGraphDb plugin to NovaApp?"
48 )
49 }
50}
51
52impl std::error::Error for NovaGraphRejection {}
53
54impl IntoResponse for NovaGraphRejection {
55 fn into_response(self) -> Response {
56 (
57 StatusCode::INTERNAL_SERVER_ERROR,
58 "Graph database not configured",
59 )
60 .into_response()
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use axum::extract::FromRequestParts;
68 use axum::http::Request;
69
70 #[tokio::test]
71 async fn extracts_graph_from_extensions() {
72 let graph = crate::NovaGraphDb::in_memory();
73 let (mut parts, _) = Request::new(()).into_parts();
74 parts.extensions.insert(graph);
75
76 let extracted = NovaGraph::from_request_parts(&mut parts, &()).await;
77
78 assert!(extracted.is_ok());
79 }
80
81 #[tokio::test]
82 async fn rejects_when_graph_is_missing() {
83 let (mut parts, _) = Request::new(()).into_parts();
84
85 let rejection = NovaGraph::from_request_parts(&mut parts, &())
86 .await
87 .expect_err("expected missing graph rejection");
88
89 assert!(rejection.to_string().contains("NovaGraphDb"));
90 assert_eq!(
91 rejection.into_response().status(),
92 StatusCode::INTERNAL_SERVER_ERROR
93 );
94 }
95}