Skip to main content

Crate jerrycan

Crate jerrycan 

Source
Expand description

The AI-native Rust backend platform. Generated apps depend on this one crate (plus tokio) and write use jerrycan::prelude::*;. The CLI/MCP binary joins this package in Phase 1 behind a cli feature.

Re-exports§

pub use jerrycan_db as db;

Modules§

app
App (spec §4.1): assembles mounted modules + app-level routes, validates the route table at build time (fail loud), and dispatches requests.
clock
Injectable time. Handlers/extensions take Dep<Clock> and call now(); tests control it via TestApp::clock().advance(..). The serve engine’s own timeouts deliberately stay on real tokio time — Clock is for DOMAIN time (rate windows, schedules, expiry), not transport timeouts.
cors
CORS (spec §v2.2). Lives in core because preflight must be answered BEFORE routing (an OPTIONS to a method-mismatched route is rejected 405 before any middleware runs), so CORS is a pre-routing + response-decoration concern integrated into route_policy/dispatch in later tasks — not a Middleware.
dep
Dependency injection (spec §4.3) — async, nested, per-request memoized, override-able in tests. Resolution order: cache → overrides → singletons → factories. Singletons and factories are disjoint by construction (insert_value/insert_factory each remove the opposite key), so there is no singleton-vs-factory tiebreak to define.
error
jerrycan’s single error type. Every error carries a stable code (JC####) that maps to a documentation anchor — the error-driven-docs contract (spec §8).
extract
Request context and extractors (spec §4.1). Everything a handler needs is visible in its signature; each parameter implements FromRequest.
handler
Handler abstraction (spec §4.1): a handler is a plain async fn whose parameters implement FromRequest and whose return implements IntoResponse. Extraction failures short-circuit into error responses.
http
A general purpose library of common HTTP types
middleware
Middleware (spec §4.1): async fn handle(&self, ctx, next). Composable, ordering explicit, no tower, no magic.
module
Module (spec §4.2): the unit of routing, packaging, and ownership. Bundles routes, nested subroutes, module-scoped dependencies and middleware. Flattening composes URL prefixes and layers environments (inner wins).
multipart
multipart/form-data (RFC 7578). The parser half is a pure incremental state machine — fed chunks, drained as events, no IO — so the grammar is unit-testable at every chunk straddle and fuzzable in isolation (fuzz/fuzz_targets/multipart_parse.rs). The extractor half (Task 7) adapts it to the request body lanes.
platform
The jerrycan platform: shared core consumed by both the CLI (main.rs) and the MCP server (platform::mcp). One pipeline, two renderings (cli-ux.md).
prelude
response
Response model. Handlers return anything implementing IntoResponse; Result<T, Error> renders errors as {"code","message"} JSON (spec §4.1).
router
Method routing + segment trie with {param} captures (spec §4.1). Conflicting routes are detected at build time — fail loud before serving. Path segments are percent-decoded after ‘/’-splitting; malformed encodings surface as RouteMatch::Malformed (a clean 400, never a panic).
serde_json
Serde JSON
serde_urlencoded
x-www-form-urlencoded meets Serde
test_client
In-memory test client (spec §4.1 “Test client”): no sockets, no network. override_dep is THE testing seam — fake any dependency, run real requests.

Macros§

path_param
#[macro_export] lands path_param! at the jerrycan_core crate root; this re-export makes jerrycan::path_param! resolve through the facade. Admit a custom newtype as a Path parameter. The type must implement FromStr with a Display error; a parse failure maps to the same JC0400 invalid-path-parameter error the built-in impls produce.

Structs§

App
The application builder. Generated app/src/main.rs is exactly this: provide app-level deps, mount modules, serve.
BodyError
Mid-stream body failure. Reaching hyper as a body error aborts the connection, so the client sees a truncated (invalid) chunked stream rather than a clean end — truncation must be detectable.
BodySender
Push side of StreamBody::channel.
BuiltApp
The frozen, immutable runtime form. Cheap to share across connections.
Clock
An injectable source of “now”. Cloning is cheap and, for a test clock, shares the same controllable offset — so a handle handed to a test moves in lockstep with the clock the handler resolves.
CorsConfig
CORS policy. Build with CorsConfig::new(origins), chain options, install with App::cors(config).
Created
201 Created with a JSON body.
Dep
A resolved dependency. Derefs to T; cloning is Arc-cheap.
Error
The one error type of the framework (spec §4.1 “Errors”).
Headers
Read-only access to request headers in a handler signature.
JcBody
The response body: a fixed buffer for buffered handlers, or a stream when a handler returns StreamBody (downloads, exports). Wraps a BoxBody so the response type is stable whichever shape the body takes; its error channel is BodyError, which a mid-stream failure rides to abort the connection.
Json
JSON body wrapper: Json(value) serializes with application/json.
MethodRouter
Per-path method table: get(list).post(create) (spec §4.1).
Module
Flask’s Blueprint, Rust-grade. Built by route crates’ pub fn module().
Multipart
Streaming multipart/form-data extractor. Parts arrive in wire order and must be consumed sequentially; next_part discards any unread remainder of the previous part. Requires content-type: multipart/form-data with a valid boundary — anything else is 415 JC0415.
Next
The remainder of the middleware chain plus the endpoint handler.
NoContent
204 No Content.
Path
Typed path parameter: Path<i64> binds the LEAF-MOST (last) captured parameter; use a tuple to address all parameters root→leaf — Path<(A, B)> / Path<(A, B, C)> grab two/three {param}s in route order. Param types are the sealed PathParam set (integers, String, bool, floats, char); custom newtypes opt in through the path_param! macro.
PathParams
A by-name view of the request’s captured path parameters. Where Path<T> binds positionally (the leaf-most segment, or a root→leaf tuple), PathParams reads a SPECIFIC mount param BY NAME — the accessor a DI factory needs, since a factory resolves each argument through FromRequest and cannot borrow &RequestCtx to call RequestCtx::param. The membership-verifying tenancy guard uses it to read the tenant fk club_id under /clubs/{club_id} even when a leaf {id} follows (issues #78/#79). Rejects a task context (JC1003), like every other HTTP-coupled extractor.
Query
Typed query string: Query<MyParams> via serde.
RawBody
The request body as EXACT bytes — the extractor for webhook signature verification, where the digest must cover the wire bytes, not a re-serialized value. Works on buffered routes (cheap clone) and stream_body() routes (drains and caches). See the auth docs for the Stripe/Twilio recipes.
Redirect
An HTTP redirect: an empty body plus a Location header and a 3xx status. Use the constructor that names the semantics you want — to/see_other/ temporary/permanent — rather than hand-setting a status code.
RequestCtx
The mutable view of one in-flight request. Handlers receive extractors, not this type; middleware and the DI resolver work through it.
StreamBody
A streaming response body: downloads, CSV exports, anything produced incrementally. Defaults: application/octet-stream, 200 OK, 30s frame timeout (a producer that stalls longer aborts the connection).
TaskContext
Resolve dependencies OUTSIDE an HTTP request — background jobs, startup wiring, CLI commands. Built from BuiltApp::task_context.
TestApp
TestPart
One part for TestApp::post_multipart.
TestResponse

Enums§

CorsOrigins
Which origins may make cross-origin requests.

Traits§

Extension
Spec §6: capabilities register through one seam. An extension receives the builder and returns it — providers, routes, middleware, anything.
FromRequest
Types that can be produced from the request. Implemented by all extractors and by Dep<T> (see dep module).
Handler
Implemented for async fns of arity 0..=8 over FromRequest parameters.
IntoResponse
Conversion of handler return values into HTTP responses.
Middleware
Wraps request handling. Call next.run(&mut *ctx).await to continue; return early to short-circuit (auth rejections, rate limits, …).

Functions§

delete
get
now_rfc3339
The current UTC instant as an RFC3339 string with seconds precision and a Z suffix (e.g. 2026-07-26T12:34:56Z) — the exact shape jerrycan’s datetime fields ride as (String) and the OpenAPI/fixture format uses.
patch
post
put

Type Aliases§

MiddlewareFuture
Boxed future returned by middleware. The lifetime ties to the request.
Response
The concrete response type. Streaming bodies ride the same IntoResponse seam as buffered ones, so handler signatures won’t change.
Result
Convenience alias used across jerrycan and generated apps.

Attribute Macros§

main
#[jerrycan::main] — boots the async runtime around async fn main. Delegates to #[tokio::main]; the app must (and generated apps do) depend on tokio directly. The user’s tokens pass through UNCHANGED, preserving their spans so compiler diagnostics point at the user’s code, not at this attribute.