Skip to content

Commit

Permalink
You can't build a Response from a constructor. (LukeMathWalker#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeMathWalker authored Mar 29, 2024
1 parent 38489e7 commit 6cec7f4
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,51 @@
│ `pavex::Error` can only be used as the error type of your fallible
│ components.
│
│ ╭─[src/lib.rs:72:1]
│ 72 │ let mut bp = Blueprint::new();
│ 73 │ bp.constructor(f!(crate::error_ref), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:81:1]
│ 81 │ let mut bp = Blueprint::new();
│ 82 │ bp.constructor(f!(crate::error_ref), Lifecycle::RequestScoped);
│ ·  ──────────┬─────────
│ · ╰── The constructor was registered here
│ 74 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ 83 │ bp.constructor(f!(crate::response_ref), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::Response`.
│ You can only return a response from request handlers, middlewares or error
│ handlers.
│
│ ╭─[src/lib.rs:82:1]
│ 82 │ bp.constructor(f!(crate::error_ref), Lifecycle::RequestScoped);
│ 83 │ bp.constructor(f!(crate::response_ref), Lifecycle::RequestScoped);
│ ·  ───────────┬───────────
│ · ╰── The constructor was registered here
│ 84 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::request::RequestHead`.
│ `pavex::request::RequestHead` is a framework primitive, you can't override
│ the way it's built by Pavex.
│
│ ╭─[src/lib.rs:73:1]
│ 73 │ bp.constructor(f!(crate::error_ref), Lifecycle::RequestScoped);
│ 74 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:83:1]
│ 83 │ bp.constructor(f!(crate::response_ref), Lifecycle::RequestScoped);
│ 84 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ ·  ─────────────┬─────────────
│ · ╰── The constructor was registered here
│ 75 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ 85 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::router::AllowedMethods`.
│ `pavex::router::AllowedMethods` is a framework primitive, you can't
│ override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:74:1]
│ 74 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ 75 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:84:1]
│ 84 │ bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
│ 85 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ ·  ───────────────┬──────────────
│ · ╰── The constructor was registered here
│ 76 │ bp.constructor(f!(crate::raw_incoming_body_ref), Lifecycle::RequestScoped);
│ 86 │ bp.constructor(f!(crate::raw_incoming_body_ref), Lifecycle::RequestScoped);
│ ╰────

ERROR:
Expand All @@ -43,12 +56,12 @@
│ `pavex::request::body::RawIncomingBody` is a framework primitive, you
│ can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:75:1]
│ 75 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ 76 │ bp.constructor(f!(crate::raw_incoming_body_ref), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:85:1]
│ 85 │ bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
│ 86 │ bp.constructor(f!(crate::raw_incoming_body_ref), Lifecycle::RequestScoped);
│ ·  ────────────────┬───────────────
│ · ╰── The constructor was registered here
│ 77 │ bp.constructor(
│ 87 │ bp.constructor(
│ ╰────

ERROR:
Expand All @@ -57,12 +70,12 @@
│ `pavex::request::path::MatchedPathPattern` is a framework primitive, you
│ can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:77:1]
│ 77 │ bp.constructor(
│ 78 │ f!(crate::matched_path_pattern_ref),
│ ╭─[src/lib.rs:87:1]
│ 87 │ bp.constructor(
│ 88 │ f!(crate::matched_path_pattern_ref),
│ ·  ─────────────────┬─────────────────
│ · ╰── The constructor was registered here
│ 79 │ Lifecycle::RequestScoped,
│ 89 │ Lifecycle::RequestScoped,
│ ╰────

ERROR:
Expand All @@ -71,51 +84,64 @@
│ `pavex::request::path::RawPathParams<'server, 'request>` is a framework
│ primitive, you can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:80:1]
│ 80 │ );
│ 81 │ bp.constructor(f!(crate::raw_path_params_ref), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:90:1]
│ 90 │ );
│ 91 │ bp.constructor(f!(crate::raw_path_params_ref), Lifecycle::RequestScoped);
│ ·  ───────────────┬──────────────
│ · ╰── The constructor was registered here
│ 82 │ bp
│ 92 │ bp
│ ╰────

ERROR:
× You can't register a constructor for `pavex::Error`.
│ `pavex::Error` can only be used as the error type of your fallible
│ components.
│
│ ╭─[src/lib.rs:62:1]
│ 62 │ let mut bp = Blueprint::new();
│ 63 │ bp.constructor(f!(crate::error), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:70:1]
│ 70 │ let mut bp = Blueprint::new();
│ 71 │ bp.constructor(f!(crate::error), Lifecycle::RequestScoped);
│ ·  ────────┬───────
│ · ╰── The constructor was registered here
│ 64 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ 72 │ bp.constructor(f!(crate::response), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::Response`.
│ You can only return a response from request handlers, middlewares or error
│ handlers.
│
│ ╭─[src/lib.rs:71:1]
│ 71 │ bp.constructor(f!(crate::error), Lifecycle::RequestScoped);
│ 72 │ bp.constructor(f!(crate::response), Lifecycle::RequestScoped);
│ ·  ─────────┬─────────
│ · ╰── The constructor was registered here
│ 73 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::request::RequestHead`.
│ `pavex::request::RequestHead` is a framework primitive, you can't override
│ the way it's built by Pavex.
│
│ ╭─[src/lib.rs:63:1]
│ 63 │ bp.constructor(f!(crate::error), Lifecycle::RequestScoped);
│ 64 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:72:1]
│ 72 │ bp.constructor(f!(crate::response), Lifecycle::RequestScoped);
│ 73 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ ·  ───────────┬───────────
│ · ╰── The constructor was registered here
│ 65 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ 74 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ ╰────

ERROR:
× You can't register a constructor for `pavex::router::AllowedMethods`.
│ `pavex::router::AllowedMethods` is a framework primitive, you can't
│ override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:64:1]
│ 64 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ 65 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:73:1]
│ 73 │ bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
│ 74 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ ·  ─────────────┬────────────
│ · ╰── The constructor was registered here
│ 66 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ 75 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ ╰────

ERROR:
Expand All @@ -124,12 +150,12 @@
│ `pavex::request::body::RawIncomingBody` is a framework primitive, you
│ can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:65:1]
│ 65 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ 66 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:74:1]
│ 74 │ bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
│ 75 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ ·  ──────────────┬─────────────
│ · ╰── The constructor was registered here
│ 67 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ 76 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ ╰────

ERROR:
Expand All @@ -138,12 +164,12 @@
│ `pavex::request::path::MatchedPathPattern` is a framework primitive, you
│ can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:66:1]
│ 66 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ 67 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:75:1]
│ 75 │ bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
│ 76 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ ·  ───────────────┬───────────────
│ · ╰── The constructor was registered here
│ 68 │ bp.constructor(f!(crate::raw_path_params), Lifecycle::RequestScoped);
│ 77 │ bp.constructor(f!(crate::raw_path_params), Lifecycle::RequestScoped);
│ ╰────

ERROR:
Expand All @@ -152,10 +178,10 @@
│ `pavex::request::path::RawPathParams<'server, 'request>` is a framework
│ primitive, you can't override the way it's built by Pavex.
│
│ ╭─[src/lib.rs:67:1]
│ 67 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ 68 │ bp.constructor(f!(crate::raw_path_params), Lifecycle::RequestScoped);
│ ╭─[src/lib.rs:76:1]
│ 76 │ bp.constructor(f!(crate::matched_path_pattern), Lifecycle::RequestScoped);
│ 77 │ bp.constructor(f!(crate::raw_path_params), Lifecycle::RequestScoped);
│ ·  ─────────────┬────────────
│ · ╰── The constructor was registered here
│ 69 │ bp
│ 78 │ bp
│ ╰────
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ pub fn error_ref(request_head: &RequestHead) -> &pavex::Error {
todo!()
}

pub fn response() -> pavex::response::Response {
todo!()
}

pub fn response_ref(request_head: &RequestHead) -> &pavex::response::Response {
todo!()
}

pub fn request_head() -> RequestHead {
todo!()
}
Expand Down Expand Up @@ -61,6 +69,7 @@ pub fn blueprint() -> Blueprint {
bp.nest({
let mut bp = Blueprint::new();
bp.constructor(f!(crate::error), Lifecycle::RequestScoped);
bp.constructor(f!(crate::response), Lifecycle::RequestScoped);
bp.constructor(f!(crate::request_head), Lifecycle::RequestScoped);
bp.constructor(f!(crate::allowed_methods), Lifecycle::RequestScoped);
bp.constructor(f!(crate::raw_incoming_body), Lifecycle::RequestScoped);
Expand All @@ -71,6 +80,7 @@ pub fn blueprint() -> Blueprint {
bp.nest({
let mut bp = Blueprint::new();
bp.constructor(f!(crate::error_ref), Lifecycle::RequestScoped);
bp.constructor(f!(crate::response_ref), Lifecycle::RequestScoped);
bp.constructor(f!(crate::request_head_ref), Lifecycle::RequestScoped);
bp.constructor(f!(crate::allowed_methods_ref), Lifecycle::RequestScoped);
bp.constructor(f!(crate::raw_incoming_body_ref), Lifecycle::RequestScoped);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl ComponentDb {
}
ConstructorValidationError::CannotFalliblyReturnTheUnitType
| ConstructorValidationError::CannotConstructPavexError
| ConstructorValidationError::CannotConstructPavexResponse
| ConstructorValidationError::CannotConstructFrameworkPrimitive { .. }
| ConstructorValidationError::CannotReturnTheUnitType => {
let d = CompilerDiagnostic::builder(e)
Expand Down
14 changes: 12 additions & 2 deletions libs/pavexc/src/compiler/analyses/components/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,12 @@ impl ComponentDb {
.collect::<Vec<_>>();
for user_component_id in constructor_ids {
let c: Computation = computation_db[user_component_id].clone().into();
match Constructor::new(c, &self.pavex_error, framework_item_db) {
match Constructor::new(
c,
&self.pavex_error,
&self.pavex_response,
framework_item_db,
) {
Err(e) => {
Self::invalid_constructor(
e,
Expand Down Expand Up @@ -1138,7 +1143,12 @@ impl ComponentDb {
derived_from: Option<ComponentId>,
) -> Result<ComponentId, ConstructorValidationError> {
let callable = computation_db[callable_id].to_owned();
Constructor::new(callable, &self.pavex_error, &framework_item_db)?;
Constructor::new(
callable,
&self.pavex_error,
&self.pavex_response,
&framework_item_db,
)?;
let constructor_component = UnregisteredComponent::SyntheticConstructor {
lifecycle,
computation_id: callable_id,
Expand Down
Loading

0 comments on commit 6cec7f4

Please sign in to comment.