Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect additional breadcrumbs to reduce the situations where we can't identify an external rustdoc JSON crate. #188

Merged
merged 1 commit into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Do NOT edit this code.
//! It was automatically generated by Pavex.
//! All manual edits will be lost next time the code is generated.
extern crate alloc;
struct ServerState {
router: pavex_matchit::Router<u32>,
#[allow(dead_code)]
application_state: ApplicationState,
}
pub struct ApplicationState {}
pub async fn build_application_state() -> crate::ApplicationState {
crate::ApplicationState {}
}
pub fn run(
server_builder: pavex::server::Server,
application_state: ApplicationState,
) -> pavex::server::ServerHandle {
let server_state = std::sync::Arc::new(ServerState {
router: build_router(),
application_state,
});
server_builder.serve(route_request, server_state)
}
fn build_router() -> pavex_matchit::Router<u32> {
let mut router = pavex_matchit::Router::new();
router.insert("/home", 0u32).unwrap();
router
}
async fn route_request(
request: http::Request<hyper::body::Incoming>,
server_state: std::sync::Arc<ServerState>,
) -> pavex::response::Response {
let (request_head, request_body) = request.into_parts();
#[allow(unused)]
let request_body = pavex::request::body::RawIncomingBody::from(request_body);
let request_head: pavex::request::RequestHead = request_head.into();
let matched_route = match server_state.router.at(&request_head.target.path()) {
Ok(m) => m,
Err(_) => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter(
vec![],
)
.into();
return route_1::handler(&allowed_methods).await;
}
};
let route_id = matched_route.value;
#[allow(unused)]
let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route
.params
.into();
match route_id {
0u32 => {
match &request_head.method {
&pavex::http::Method::GET => route_0::handler().await,
_ => {
let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([
pavex::http::Method::GET,
])
.into();
route_1::handler(&allowed_methods).await
}
}
}
i => unreachable!("Unknown route id: {}", i),
}
}
pub mod route_0 {
pub async fn handler() -> pavex::response::Response {
let v0 = app::handler();
<http::StatusCode as pavex::response::IntoResponse>::into_response(v0)
}
}
pub mod route_1 {
pub async fn handler(
v0: &pavex::router::AllowedMethods,
) -> pavex::response::Response {
let v1 = pavex::router::default_fallback(v0).await;
<pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
digraph "GET /home - 0" {
0 [ label = "app::handler() -> http::StatusCode"]
1 [ label = "<http::StatusCode as pavex::response::IntoResponse>::into_response(http::StatusCode) -> pavex::response::Response"]
0 -> 1 [ ]
}

digraph "* /home - 0" {
0 [ label = "pavex::router::default_fallback(&pavex::router::AllowedMethods) -> pavex::response::Response"]
2 [ label = "<pavex::response::Response as pavex::response::IntoResponse>::into_response(pavex::response::Response) -> pavex::response::Response"]
3 [ label = "&pavex::router::AllowedMethods"]
0 -> 2 [ ]
3 -> 0 [ ]
}

digraph app_state {
0 [ label = "crate::ApplicationState() -> crate::ApplicationState"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use pavex::blueprint::{router::GET, Blueprint};
use pavex::f;
use pavex::http::StatusCode;

pub fn handler() -> StatusCode {
todo!()
}

pub fn blueprint() -> Blueprint {
let mut bp = Blueprint::new();
bp.route(GET, "/home", f!(crate::handler));
bp
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
description = """Pavex can handle multiple versions of the same
package in the project dependency tree, as long as they aren't all
**direct** dependencies of the project"""

[expectations]
codegen = "pass"

[dependencies]
# This depends on a different version of `http` than what `pavex` brings in
reqwest = { version = "0.11", features = ["json"] }


24 changes: 20 additions & 4 deletions libs/pavexc/src/compiler/resolvers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,25 @@ pub(crate) fn resolve_type(
generic_bindings: &HashMap<String, ResolvedType>,
) -> Result<ResolvedType, anyhow::Error> {
match type_ {
Type::ResolvedPath(rustdoc_types::Path { id, args, .. }) => {
let (global_type_id, base_type) =
krate_collection.get_canonical_path_by_local_type_id(used_by_package_id, id)?;
Type::ResolvedPath(rustdoc_types::Path { id, args, name }) => {
let re_exporter_crate_name = if id.0.starts_with("0:") {
// 0 is the crate index of local types.
None
} else {
// It is not guaranteed that this type will be from a direct dependency of `used_by_package_id`.
// It might be a re-export from a transitive dependency, done by a direct dependency.
// Unfortunately, `rustdoc` does not provide the package id of the crate where the type
// was re-exported from, creating a "missing link".
// We try to infer it from the `name` property, which is usually the fully qualified
// name of the type, e.g. `std::collections::HashMap`.
name.split("::").next()
};
let (global_type_id, base_type) = krate_collection
.get_canonical_path_by_local_type_id(
used_by_package_id,
id,
re_exporter_crate_name,
)?;
let type_item = krate_collection.get_type_by_global_type_id(&global_type_id);
// We want to remove any indirections (e.g. `type Foo = Bar;`) and get the actual type.
if let ItemEnum::TypeAlias(type_alias) = &type_item.inner {
Expand Down Expand Up @@ -420,7 +436,7 @@ pub(crate) fn resolve_type_path(
let item = &resolved_item.item;
let used_by_package_id = resolved_item.item_id.package_id();
let (global_type_id, base_type) =
krate_collection.get_canonical_path_by_local_type_id(used_by_package_id, &item.id)?;
krate_collection.get_canonical_path_by_local_type_id(used_by_package_id, &item.id, None)?;
let mut generic_arguments = vec![];
let (last_segment, first_segments) = path.segments.split_last().unwrap();
for segment in first_segments {
Expand Down
8 changes: 6 additions & 2 deletions libs/pavexc/src/compiler/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ pub(crate) fn implements_trait(
};
if let Some(trait_id) = trait_id {
if let Ok((_, trait_path)) = krate_collection
.get_canonical_path_by_local_type_id(&our_path_type.package_id, trait_id)
.get_canonical_path_by_local_type_id(
&our_path_type.package_id,
trait_id,
None,
)
{
if trait_path == expected_trait.base_type
// The "impls" for a rustdoc item include implementations for
Expand Down Expand Up @@ -275,7 +279,7 @@ fn is_equivalent(
};
let rustdoc_type_id = &p.id;
let Ok((rustdoc_global_type_id, _)) = krate_collection
.get_canonical_path_by_local_type_id(used_by_package_id, rustdoc_type_id)
.get_canonical_path_by_local_type_id(used_by_package_id, rustdoc_type_id, None)
else {
tracing::trace!("Failed to look up {:?}", rustdoc_type_id);
return false;
Expand Down
2 changes: 1 addition & 1 deletion libs/pavexc/src/language/resolved_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl ResolvedPathType {
let item = &resolved_item.item;
let used_by_package_id = resolved_item.item_id.package_id();
let (global_type_id, base_type) = krate_collection
.get_canonical_path_by_local_type_id(used_by_package_id, &item.id)?;
.get_canonical_path_by_local_type_id(used_by_package_id, &item.id, None)?;
let mut generic_arguments = vec![];
for segment in &p.path.segments {
for generic_path in &segment.generic_arguments {
Expand Down
Loading
Loading