@ -95,6 +95,7 @@ fn default_page() -> u32 {
/// The spec is embedded at compile time from `api/openapi.yaml` (converted to
/// The spec is embedded at compile time from `api/openapi.yaml` (converted to
/// JSON by `build.rs`). Returns `Content-Type: application/json` with the raw
/// JSON by `build.rs`). Returns `Content-Type: application/json` with the raw
/// spec string.
/// spec string.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn openapi_handler ( ) -> Response {
async fn openapi_handler ( ) -> Response {
const OPENAPI_JSON : & str = include_str! ( concat! ( env! ( "OUT_DIR" ) , "/openapi.json" ) ) ;
const OPENAPI_JSON : & str = include_str! ( concat! ( env! ( "OUT_DIR" ) , "/openapi.json" ) ) ;
(
(
@ -109,6 +110,7 @@ async fn openapi_handler() -> Response {
///
///
/// Accepts `?page=N&author=X&tag=Y` query parameters. Defaults to page 1 and
/// Accepts `?page=N&author=X&tag=Y` query parameters. Defaults to page 1 and
/// no filters. Returns [`crate::db::ListResult`] serialised as JSON.
/// no filters. Returns [`crate::db::ListResult`] serialised as JSON.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn list_handler ( State ( repo ) : State < Repo > , Query ( params ) : Query < ListParams > ) -> Response {
async fn list_handler ( State ( repo ) : State < Repo > , Query ( params ) : Query < ListParams > ) -> Response {
match repo
match repo
. list_quotes ( params . page , params . author . as_deref ( ) , params . tag . as_deref ( ) )
. list_quotes ( params . page , params . author . as_deref ( ) , params . tag . as_deref ( ) )
@ -126,6 +128,7 @@ async fn list_handler(State(repo): State<Repo>, Query(params): Query<ListParams>
/// **Registration order:** this route must be registered before
/// **Registration order:** this route must be registered before
/// `GET /api/quotes/:id` in the router to avoid "random" being matched as an
/// `GET /api/quotes/:id` in the router to avoid "random" being matched as an
/// id parameter.
/// id parameter.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn random_handler ( State ( repo ) : State < Repo > ) -> Response {
async fn random_handler ( State ( repo ) : State < Repo > ) -> Response {
match repo . get_random_quote ( ) . await {
match repo . get_random_quote ( ) . await {
Ok ( Some ( quote ) ) = > ( StatusCode ::OK , Json ( quote ) ) . into_response ( ) ,
Ok ( Some ( quote ) ) = > ( StatusCode ::OK , Json ( quote ) ) . into_response ( ) ,
@ -137,6 +140,7 @@ async fn random_handler(State(repo): State<Repo>) -> Response {
/// `GET /api/quotes/:id` — retrieve a single quote by NanoID.
/// `GET /api/quotes/:id` — retrieve a single quote by NanoID.
///
///
/// Returns `404` when no quote has the given id.
/// Returns `404` when no quote has the given id.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn get_quote_handler ( State ( repo ) : State < Repo > , Path ( id ) : Path < String > ) -> Response {
async fn get_quote_handler ( State ( repo ) : State < Repo > , Path ( id ) : Path < String > ) -> Response {
match repo . get_quote ( & id ) . await {
match repo . get_quote ( & id ) . await {
Ok ( Some ( quote ) ) = > ( StatusCode ::OK , Json ( quote ) ) . into_response ( ) ,
Ok ( Some ( quote ) ) = > ( StatusCode ::OK , Json ( quote ) ) . into_response ( ) ,
@ -150,6 +154,7 @@ async fn get_quote_handler(State(repo): State<Repo>, Path(id): Path<String>) ->
/// Accepts a JSON body matching [`CreateQuoteInput`]. Returns `201 Created`
/// Accepts a JSON body matching [`CreateQuoteInput`]. Returns `201 Created`
/// with `{"quote": {...}, "auth_code": "..."}`. The `auth_code` is the only
/// with `{"quote": {...}, "auth_code": "..."}`. The `auth_code` is the only
/// time it is returned — the client must store it.
/// time it is returned — the client must store it.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn create_handler ( State ( repo ) : State < Repo > , Json ( input ) : Json < CreateQuoteInput > ) -> Response {
async fn create_handler ( State ( repo ) : State < Repo > , Json ( input ) : Json < CreateQuoteInput > ) -> Response {
match repo . create_quote ( input ) . await {
match repo . create_quote ( input ) . await {
Ok ( ( quote , auth_code ) ) = > (
Ok ( ( quote , auth_code ) ) = > (
@ -175,6 +180,7 @@ fn extract_auth_code(headers: &HeaderMap) -> Option<String> {
///
///
/// Requires the `X-Auth-Code` header. Returns `403` if missing or wrong,
/// Requires the `X-Auth-Code` header. Returns `403` if missing or wrong,
/// `404` if the quote does not exist, or `200` with the updated quote.
/// `404` if the quote does not exist, or `200` with the updated quote.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn update_handler (
async fn update_handler (
State ( repo ) : State < Repo > ,
State ( repo ) : State < Repo > ,
Path ( id ) : Path < String > ,
Path ( id ) : Path < String > ,
@ -195,6 +201,7 @@ async fn update_handler(
///
///
/// Requires the `X-Auth-Code` header. Returns `403` if missing or wrong,
/// Requires the `X-Auth-Code` header. Returns `403` if missing or wrong,
/// `404` if not found, or `204 No Content` on success.
/// `404` if not found, or `204 No Content` on success.
#[ cfg_attr(target_arch = " wasm32 " , worker::send) ]
async fn delete_handler (
async fn delete_handler (
State ( repo ) : State < Repo > ,
State ( repo ) : State < Repo > ,
Path ( id ) : Path < String > ,
Path ( id ) : Path < String > ,