Something went wrong. Try again.
An opinionated framework for small task-based applications.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108use axum::{ Router, extract::{Path, Query, State}, http::StatusCode, response::{Html, Redirect, Result}, routing::{get, post},};use minijinja::context;use serde::Serialize;use serde_qs::web::QsForm;use wallsocket_core::{ Database, schema::{CompletedSchema, Schema},};use wallsocket_input::{Id, PendingInputRequest};
use crate::{AppState, helpers::Pagination};
use std::{ops::Deref, str::FromStr, sync::Arc};
pub fn router<D: Deref<Target = Database> + Send + Sync + 'static>() -> Router<Arc<AppState<D>>> { Router::new() .route("/input", get(pending_input::<D>)) .route("/input/{id}/submit", post(submit_input::<D>))}
#[derive(Debug, Clone, Serialize)]struct PendingInput { id: String, request: Schema,}
async fn pending_input<D: Deref<Target = Database> + Send + Sync + 'static>( page: Query<Pagination>, State(state): State<Arc<AppState<D>>>,) -> Result<Html<String>> { let after = if let Some(after) = &page.after { Some(Id::from_str(after).map_err(|e| { ( StatusCode::BAD_REQUEST, format!("error parsing `after`: {e}"), ) })?) } else { None }; let results: Vec<_> = state .config .input_registry .pending() .await .iter() .skip_while(|p| { if let Some(after) = after { p.id <= after } else { false // don't skip anything, ie start at the beginning } }) .take(page.limit) .map(PendingInput::from) .collect();
Ok(Html( state .templates .get_template("pending_inputs") .unwrap() .render(context! { results }) .unwrap(), ))}
impl From<&PendingInputRequest> for PendingInput { fn from(value: &PendingInputRequest) -> Self { Self { id: value.id.to_string(), request: value.request.clone(), } }}
async fn submit_input<D: Deref<Target = Database> + Send + Sync + 'static>( State(state): State<Arc<AppState<D>>>, Path(id): Path<String>, QsForm(body): QsForm<CompletedSchema>,) -> Result<Redirect> { state .config .input_registry .answer( Id::from_str(&id) .map_err(|e| (StatusCode::BAD_REQUEST, format!("error parsing `id`: {e}")))?, body, ) .await .map_err(|e| { ( StatusCode::BAD_REQUEST, format!("error answering input request: {e}"), ) })?;
Ok(Redirect::to("/input"))}