Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
assets/myadam.jpg
.github/copilot-instructions.md
docs/UPDATE_SUMMARIES.md
assets/cb7d0daf60d7675081996d81393e2ae5.jpg
assets/b9c93c1cd427d8f50e68dbd11ed2b000.jpg
12 changes: 7 additions & 5 deletions crates/rustapi-core/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,19 @@ impl RustApi {
entry.insert_boxed_with_operation(method_enum, route.handler, route.operation);
}

let route_count = by_path
#[cfg(feature = "tracing")]
let route_count: usize = by_path
.values()
.map(|mr| mr.allowed_methods().len())
.sum::<usize>();
.sum();
#[cfg(feature = "tracing")]
let path_count = by_path.len();

for (path, method_router) in by_path {
self = self.route(&path, method_router);
}

tracing::info!(
crate::trace_info!(
paths = path_count,
routes = route_count,
"Auto-registered routes"
Expand Down Expand Up @@ -887,12 +889,12 @@ impl Default for RustApi {
mod tests {
use super::RustApi;
use crate::extract::{FromRequestParts, State};
use crate::path_params::PathParams;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams is imported but doesn't exist in the codebase. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
use crate::request::Request;
use crate::router::{get, post, Router};
use bytes::Bytes;
use http::Method;
use proptest::prelude::*;
use std::collections::HashMap;

#[test]
fn state_is_available_via_extractor() {
Expand All @@ -906,7 +908,7 @@ mod tests {
.unwrap();
let (parts, _) = req.into_parts();

let request = Request::new(parts, Bytes::new(), router.state_ref(), HashMap::new());
let request = Request::new(parts, Bytes::new(), router.state_ref(), PathParams::new());
let State(value) = State::<u32>::from_request_parts(&request).unwrap();
assert_eq!(value, 123u32);
}
Expand Down
37 changes: 26 additions & 11 deletions crates/rustapi-core/src/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
//! in any order.

use crate::error::{ApiError, Result};
use crate::json;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module crate::json does not exist in the codebase. This will cause a compilation error. The PR description mentions switching to simd-json, but the module hasn't been created. You need to either create the json module with the required functions (from_slice and to_vec_with_capacity) or revert to using serde_json directly.

Suggested change
use crate::json;

Copilot uses AI. Check for mistakes.
use crate::request::Request;
use crate::response::IntoResponse;
use bytes::Bytes;
Expand Down Expand Up @@ -116,7 +117,8 @@ impl<T: DeserializeOwned + Send> FromRequest for Json<T> {
.take_body()
.ok_or_else(|| ApiError::internal("Body already consumed"))?;

let value: T = serde_json::from_slice(&body)?;
// Use simd-json accelerated parsing when available (2-4x faster)
let value: T = json::from_slice(&body)?;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function json::from_slice is called but the json module doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
Ok(Json(value))
}
}
Expand All @@ -141,10 +143,15 @@ impl<T> From<T> for Json<T> {
}
}

/// Default pre-allocation size for JSON response buffers (256 bytes)
/// This covers most small to medium JSON responses without reallocation.
const JSON_RESPONSE_INITIAL_CAPACITY: usize = 256;

// IntoResponse for Json - allows using Json<T> as a return type
impl<T: Serialize> IntoResponse for Json<T> {
fn into_response(self) -> crate::response::Response {
match serde_json::to_vec(&self.0) {
// Use pre-allocated buffer to reduce allocations
match json::to_vec_with_capacity(&self.0, JSON_RESPONSE_INITIAL_CAPACITY) {
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function json::to_vec_with_capacity is called but the json module doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
Ok(body) => http::Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "application/json")
Expand Down Expand Up @@ -199,12 +206,12 @@ impl<T> ValidatedJson<T> {

impl<T: DeserializeOwned + rustapi_validate::Validate + Send> FromRequest for ValidatedJson<T> {
async fn from_request(req: &mut Request) -> Result<Self> {
// First, deserialize the JSON body
// First, deserialize the JSON body using simd-json when available
let body = req
.take_body()
.ok_or_else(|| ApiError::internal("Body already consumed"))?;

let value: T = serde_json::from_slice(&body)?;
let value: T = json::from_slice(&body)?;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function json::from_slice is called but the json module doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.

// Then, validate it
if let Err(validation_error) = rustapi_validate::Validate::validate(&value) {
Expand Down Expand Up @@ -778,10 +785,17 @@ impl<T: for<'a> Schema<'a>> OperationModifier for Json<T> {
}
}

// Path - Placeholder for path params
// Path - Path parameters are automatically extracted from route patterns
// The add_path_params_to_operation function in app.rs handles OpenAPI documentation
// based on the {param} syntax in route paths (e.g., "/users/{id}")
impl<T> OperationModifier for Path<T> {
fn update_operation(_op: &mut Operation) {
// TODO: Implement path param extraction
// Path parameters are automatically documented by add_path_params_to_operation
// in app.rs based on the route pattern. No additional implementation needed here.
//
// For typed path params, the schema type defaults to "string" but will be
// inferred from the actual type T when more sophisticated type introspection
// is implemented.
}
}

Expand Down Expand Up @@ -885,6 +899,7 @@ impl<T: for<'a> Schema<'a>> ResponseModifier for Json<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::path_params::PathParams;
use bytes::Bytes;
use http::{Extensions, Method};
use proptest::prelude::*;
Expand Down Expand Up @@ -912,7 +927,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. Based on the code in request.rs, path parameters are still stored as HashMap<String, String>, not PathParams. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

)
}

Expand All @@ -933,7 +948,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
)
}

Expand Down Expand Up @@ -1109,7 +1124,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

);

let extracted = ClientIp::extract_with_config(&request, trust_proxy)
Expand Down Expand Up @@ -1171,7 +1186,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Suggested change
PathParams::new(),
Default::default(),

Copilot uses AI. Check for mistakes.
);

let result = Extension::<TestExtension>::from_request_parts(&request);
Expand Down Expand Up @@ -1271,7 +1286,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
);

let ip = ClientIp::extract_with_config(&request, false).unwrap();
Expand Down
6 changes: 3 additions & 3 deletions crates/rustapi-core/src/middleware/body_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ impl MiddlewareLayer for BodyLimitLayer {
#[cfg(test)]
mod tests {
use super::*;
use crate::path_params::PathParams;
use crate::request::Request;
use bytes::Bytes;
use http::{Extensions, Method};
use proptest::prelude::*;
use std::collections::HashMap;
use std::sync::Arc;

/// Create a test request with the given body
Expand All @@ -139,7 +139,7 @@ mod tests {
let req = builder.body(()).unwrap();
let (parts, _) = req.into_parts();

Request::new(parts, body, Arc::new(Extensions::new()), HashMap::new())
Request::new(parts, body, Arc::new(Extensions::new()), PathParams::new())
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
}

/// Create a test request without Content-Length header
Expand All @@ -150,7 +150,7 @@ mod tests {
let req = builder.body(()).unwrap();
let (parts, _) = req.into_parts();

Request::new(parts, body, Arc::new(Extensions::new()), HashMap::new())
Request::new(parts, body, Arc::new(Extensions::new()), PathParams::new())
}

/// Create a simple handler that returns 200 OK
Expand Down
4 changes: 2 additions & 2 deletions crates/rustapi-core/src/middleware/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,13 @@ impl Service<Request> for NextService {
#[cfg(test)]
mod tests {
use super::*;
use crate::path_params::PathParams;
use crate::request::Request;
use crate::response::Response;
use bytes::Bytes;
use http::{Extensions, Method, StatusCode};
use proptest::prelude::*;
use proptest::test_runner::TestCaseError;
use std::collections::HashMap;

/// Create a test request with the given method and path
fn create_test_request(method: Method, path: &str) -> Request {
Expand All @@ -212,7 +212,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
)
}

Expand Down
5 changes: 3 additions & 2 deletions crates/rustapi-core/src/middleware/request_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ fn generate_uuid() -> String {
mod tests {
use super::*;
use crate::middleware::layer::{BoxedNext, LayerStack};
use crate::path_params::PathParams;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams is imported but doesn't exist in the codebase. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
use bytes::Bytes;
use http::{Extensions, Method, StatusCode};
use proptest::prelude::*;
use proptest::test_runner::TestCaseError;
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use std::sync::Arc;

/// Create a test request with the given method and path
Expand All @@ -186,7 +187,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
)
}

Expand Down
3 changes: 2 additions & 1 deletion crates/rustapi-core/src/middleware/tracing_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ mod tests {
use super::*;
use crate::middleware::layer::{BoxedNext, LayerStack};
use crate::middleware::request_id::RequestIdLayer;
use crate::path_params::PathParams;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams is imported but doesn't exist in the codebase. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
use bytes::Bytes;
use http::{Extensions, Method, StatusCode};
use proptest::prelude::*;
Expand All @@ -224,7 +225,7 @@ mod tests {
parts,
Bytes::new(),
Arc::new(Extensions::new()),
HashMap::new(),
PathParams::new(),
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type PathParams doesn't exist. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
)
}

Expand Down
Loading
Loading