Skip to content

Commit 8447ffe

Browse files
feat: Add basic support for generic parameters set via trait-provided associated items
1 parent 373ee50 commit 8447ffe

File tree

37 files changed

+1611
-22
lines changed

37 files changed

+1611
-22
lines changed

compiler/ui_tests/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ members = [
291291
"reflection/arc_singletons_are_supported/generated_app",
292292
"reflection/arrays_are_supported",
293293
"reflection/arrays_are_supported/generated_app",
294+
"reflection/bitflags_are_supported",
295+
"reflection/bitflags_are_supported/generated_app",
294296
"reflection/common_response_types_are_supported",
295297
"reflection/common_response_types_are_supported/generated_app",
296298
"reflection/crate_resolution/dependencies_can_register_local_items",
@@ -319,6 +321,10 @@ members = [
319321
"reflection/output_parameter_cannot_be_handled/generated_app",
320322
"reflection/pattern_bindings_in_input_parameters_are_supported",
321323
"reflection/pattern_bindings_in_input_parameters_are_supported/generated_app",
324+
"reflection/qualified_path_default_with_blanket_impl",
325+
"reflection/qualified_path_default_with_blanket_impl/generated_app",
326+
"reflection/qualified_path_default_with_struct",
327+
"reflection/qualified_path_default_with_struct/generated_app",
322328
"reflection/raw_pointers_are_supported",
323329
"reflection/raw_pointers_are_supported/generated_app",
324330
"reflection/reexported_type_alias_work",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "app_ad701040"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
6+
[lints.rust.unexpected_cfgs]
7+
level = "allow"
8+
check-cfg = ["cfg(pavex_ide_hint)"]
9+
10+
[dependencies]
11+
enumflags2 = "0.7"
12+
workspace_hack = { version = "0.1", path = "../../workspace_hack" }
13+
14+
[dependencies.pavex]
15+
workspace = true
16+
17+
[dependencies.pavex_cli_client]
18+
workspace = true
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
digraph "* * - 0" {
2+
0 [ label = "0| &pavex::router::AllowedMethods"]
3+
1 [ label = "1| crate::route_0::Next0(&'a pavex::router::AllowedMethods) -> crate::route_0::Next0<'a>"]
4+
2 [ label = "2| pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next<crate::route_0::Next0<'a>>"]
5+
3 [ label = "3| pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_0::Next0<'a>>) -> pavex::Response"]
6+
4 [ label = "4| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
7+
2 -> 3 [ ]
8+
1 -> 2 [ ]
9+
3 -> 4 [ ]
10+
0 -> 1 [ ]
11+
}
12+
13+
digraph "* * - 1" {
14+
0 [ label = "0| &pavex::router::AllowedMethods"]
15+
1 [ label = "1| pavex::router::default_fallback(&pavex::router::AllowedMethods) -> pavex::Response"]
16+
2 [ label = "2| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
17+
1 -> 2 [ ]
18+
0 -> 1 [ ]
19+
}
20+
21+
digraph "GET / - 0" {
22+
0 [ label = "0| crate::route_1::Next0() -> crate::route_1::Next0"]
23+
1 [ label = "1| pavex::middleware::Next::new(crate::route_1::Next0) -> pavex::middleware::Next<crate::route_1::Next0>"]
24+
2 [ label = "2| pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_1::Next0>) -> pavex::Response"]
25+
3 [ label = "3| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
26+
1 -> 2 [ ]
27+
0 -> 1 [ ]
28+
2 -> 3 [ ]
29+
}
30+
31+
digraph "GET / - 1" {
32+
0 [ label = "0| app_ad701040::flags() -> enumflags2::BitFlags<app_ad701040::MyFlag, u8>"]
33+
1 [ label = "1| app_ad701040::handler(enumflags2::BitFlags<app_ad701040::MyFlag, u8>) -> pavex::Response"]
34+
2 [ label = "2| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
35+
0 -> 1 [ ]
36+
1 -> 2 [ ]
37+
}
38+
39+
digraph app_state {
40+
0 [ label = "0| crate::ApplicationState() -> crate::ApplicationState"]
41+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//! Do NOT edit this code.
2+
//! It was automatically generated by Pavex.
3+
//! All manual edits will be lost next time the code is generated.
4+
extern crate alloc;
5+
struct ServerState {
6+
router: Router,
7+
#[allow(dead_code)]
8+
application_state: ApplicationState,
9+
}
10+
#[derive(Debug, Clone, serde::Deserialize)]
11+
pub struct ApplicationConfig {}
12+
pub struct ApplicationState {}
13+
impl ApplicationState {
14+
pub async fn new(
15+
_app_config: crate::ApplicationConfig,
16+
) -> Result<crate::ApplicationState, crate::ApplicationStateError> {
17+
Ok(Self::_new().await)
18+
}
19+
async fn _new() -> crate::ApplicationState {
20+
crate::ApplicationState {}
21+
}
22+
}
23+
#[derive(Debug, thiserror::Error)]
24+
pub enum ApplicationStateError {}
25+
pub fn run(
26+
server_builder: pavex::server::Server,
27+
application_state: ApplicationState,
28+
) -> pavex::server::ServerHandle {
29+
async fn handler(
30+
request: http::Request<hyper::body::Incoming>,
31+
connection_info: Option<pavex::connection::ConnectionInfo>,
32+
server_state: std::sync::Arc<ServerState>,
33+
) -> pavex::Response {
34+
let (router, state) = (&server_state.router, &server_state.application_state);
35+
router.route(request, connection_info, state).await
36+
}
37+
let router = Router::new();
38+
let server_state = std::sync::Arc::new(ServerState {
39+
router,
40+
application_state,
41+
});
42+
server_builder.serve(handler, server_state)
43+
}
44+
struct Router {
45+
router: matchit::Router<u32>,
46+
}
47+
impl Router {
48+
/// Create a new router instance.
49+
///
50+
/// This method is invoked once, when the server starts.
51+
pub fn new() -> Self {
52+
Self { router: Self::router() }
53+
}
54+
fn router() -> matchit::Router<u32> {
55+
let mut router = matchit::Router::new();
56+
router.insert("/", 0u32).unwrap();
57+
router
58+
}
59+
pub async fn route(
60+
&self,
61+
request: http::Request<hyper::body::Incoming>,
62+
_connection_info: Option<pavex::connection::ConnectionInfo>,
63+
#[allow(unused)]
64+
state: &ApplicationState,
65+
) -> pavex::Response {
66+
let (request_head, _) = request.into_parts();
67+
let request_head: pavex::request::RequestHead = request_head.into();
68+
let Ok(matched_route) = self.router.at(&request_head.target.path()) else {
69+
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter(
70+
vec![],
71+
)
72+
.into();
73+
return route_0::entrypoint(&allowed_methods).await;
74+
};
75+
match matched_route.value {
76+
0u32 => {
77+
match &request_head.method {
78+
&pavex::http::Method::GET => route_1::entrypoint().await,
79+
_ => {
80+
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([
81+
pavex::http::Method::GET,
82+
])
83+
.into();
84+
route_0::entrypoint(&allowed_methods).await
85+
}
86+
}
87+
}
88+
i => unreachable!("Unknown route id: {}", i),
89+
}
90+
}
91+
}
92+
pub mod route_0 {
93+
pub async fn entrypoint<'a>(
94+
s_0: &'a pavex::router::AllowedMethods,
95+
) -> pavex::Response {
96+
let response = wrapping_0(s_0).await;
97+
response
98+
}
99+
async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response {
100+
let response = handler(s_0).await;
101+
response
102+
}
103+
async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response {
104+
let v1 = crate::route_0::Next0 {
105+
s_0: v0,
106+
next: stage_1,
107+
};
108+
let v2 = pavex::middleware::Next::new(v1);
109+
let v3 = pavex::middleware::wrap_noop(v2).await;
110+
<pavex::Response as pavex::IntoResponse>::into_response(v3)
111+
}
112+
async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response {
113+
let v1 = pavex::router::default_fallback(v0).await;
114+
<pavex::Response as pavex::IntoResponse>::into_response(v1)
115+
}
116+
struct Next0<'a, T>
117+
where
118+
T: std::future::Future<Output = pavex::Response>,
119+
{
120+
s_0: &'a pavex::router::AllowedMethods,
121+
next: fn(&'a pavex::router::AllowedMethods) -> T,
122+
}
123+
impl<'a, T> std::future::IntoFuture for Next0<'a, T>
124+
where
125+
T: std::future::Future<Output = pavex::Response>,
126+
{
127+
type Output = pavex::Response;
128+
type IntoFuture = T;
129+
fn into_future(self) -> Self::IntoFuture {
130+
(self.next)(self.s_0)
131+
}
132+
}
133+
}
134+
pub mod route_1 {
135+
pub async fn entrypoint() -> pavex::Response {
136+
let response = wrapping_0().await;
137+
response
138+
}
139+
async fn stage_1() -> pavex::Response {
140+
let response = handler().await;
141+
response
142+
}
143+
async fn wrapping_0() -> pavex::Response {
144+
let v0 = crate::route_1::Next0 {
145+
next: stage_1,
146+
};
147+
let v1 = pavex::middleware::Next::new(v0);
148+
let v2 = pavex::middleware::wrap_noop(v1).await;
149+
<pavex::Response as pavex::IntoResponse>::into_response(v2)
150+
}
151+
async fn handler() -> pavex::Response {
152+
let v0 = app::flags();
153+
let v1 = app::handler(v0);
154+
<pavex::Response as pavex::IntoResponse>::into_response(v1)
155+
}
156+
struct Next0<T>
157+
where
158+
T: std::future::Future<Output = pavex::Response>,
159+
{
160+
next: fn() -> T,
161+
}
162+
impl<T> std::future::IntoFuture for Next0<T>
163+
where
164+
T: std::future::Future<Output = pavex::Response>,
165+
{
166+
type Output = pavex::Response;
167+
type IntoFuture = T;
168+
fn into_future(self) -> Self::IntoFuture {
169+
(self.next)()
170+
}
171+
}
172+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
digraph "* * - 0" {
2+
0 [ label = "0| &pavex::router::AllowedMethods"]
3+
1 [ label = "1| crate::route_0::Next0(&'a pavex::router::AllowedMethods) -> crate::route_0::Next0<'a>"]
4+
2 [ label = "2| pavex::middleware::Next::new(crate::route_0::Next0<'a>) -> pavex::middleware::Next<crate::route_0::Next0<'a>>"]
5+
3 [ label = "3| pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_0::Next0<'a>>) -> pavex::Response"]
6+
4 [ label = "4| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
7+
2 -> 3 [ ]
8+
1 -> 2 [ ]
9+
3 -> 4 [ ]
10+
0 -> 1 [ ]
11+
}
12+
digraph "* * - 1" {
13+
0 [ label = "0| &pavex::router::AllowedMethods"]
14+
1 [ label = "1| pavex::router::default_fallback(&pavex::router::AllowedMethods) -> pavex::Response"]
15+
2 [ label = "2| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
16+
1 -> 2 [ ]
17+
0 -> 1 [ ]
18+
}
19+
digraph "GET / - 0" {
20+
0 [ label = "0| crate::route_1::Next0() -> crate::route_1::Next0"]
21+
1 [ label = "1| pavex::middleware::Next::new(crate::route_1::Next0) -> pavex::middleware::Next<crate::route_1::Next0>"]
22+
2 [ label = "2| pavex::middleware::wrap_noop(pavex::middleware::Next<crate::route_1::Next0>) -> pavex::Response"]
23+
3 [ label = "3| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
24+
1 -> 2 [ ]
25+
0 -> 1 [ ]
26+
2 -> 3 [ ]
27+
}
28+
digraph "GET / - 1" {
29+
0 [ label = "0| app::flags() -> enumflags2::BitFlags<app::MyFlag, u8>"]
30+
1 [ label = "1| app::handler(enumflags2::BitFlags<app::MyFlag, u8>) -> pavex::Response"]
31+
2 [ label = "2| <pavex::Response as pavex::IntoResponse>::into_response(pavex::Response) -> pavex::Response"]
32+
0 -> 1 [ ]
33+
1 -> 2 [ ]
34+
}
35+
digraph app_state {
36+
0 [ label = "0| crate::ApplicationState() -> crate::ApplicationState"]
37+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "application_ad701040"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[package.metadata.px.generate]
7+
generator_type = "cargo_workspace_binary"
8+
generator_name = "app_ad701040"
9+
10+
[dependencies]
11+
app_ad701040 = { version = "0.1", path = "..", default-features = false }
12+
enumflags2 = { version = "0.7", default-features = false }
13+
http = { version = "1", default-features = false }
14+
hyper = { version = "1", default-features = false }
15+
matchit = { version = "0.9", default-features = false }
16+
pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false }
17+
serde = { version = "1", default-features = false }
18+
thiserror = { version = "2", default-features = false }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "application_ad701040"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[package.metadata.px.generate]
7+
generator_type = "cargo_workspace_binary"
8+
generator_name = "app_ad701040"

0 commit comments

Comments
 (0)