use std::borrow::Cow; use crate::{ Db, DotJson, SqlError, Timestamp, auth::BasicAuth, directory::{Episode, Podcast}, }; use rocket::{ Route, TypedError, get, post, routes, serde::{Deserialize, Serialize, json::Json}, trace::debug, }; use rocket_db_pools::{ Connection, sqlx::{self, Connection as _}, }; #[derive(Debug, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] pub struct Device { id: String, caption: String, r#type: String, // subscriptions: usize, } #[get("/devices/<_user>.json")] pub async fn get( _user: &str, auth: BasicAuth, mut db: Connection, ) -> Result>, SqlError> { let username = auth.username(); debug!("Attempting to get devices for {username}"); let res: Vec = sqlx::query_as!( Device, "SELECT id, caption, type FROM devices WHERE user = ?", username ) .fetch_all(&mut **db) .await?; Ok(Json(res)) // todo!() } #[derive(Debug, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] pub struct DeviceUpdate<'a> { caption: Option<&'a str>, r#type: Option<&'a str>, } #[post("/devices/<_user>/.json", data = "")] pub async fn update( _user: &str, device: &str, dev: Json>, mut db: Connection, auth: BasicAuth, ) -> Result, SqlError> { let username = auth.username(); debug!("Attempting to update {device} for {username}"); let mut trans = db.begin().await?; let existing = sqlx::query_as!( Device, "SELECT id, caption, type FROM devices WHERE user = ? AND id = ?", username, device ) .fetch_optional(&mut *trans) .await?; // debug!("Users: {:?}", sqlx::query!("SELECT * FROM users").fetch_all(&mut **db).await); let res = sqlx::query("INSERT INTO devices (id, user, caption, type) VALUES (?, ?, ?, ?)") .bind(device) .bind(username) .bind( dev.caption .or(existing.as_ref().map(|d| d.caption.as_str())) .unwrap_or(""), ) .bind( dev.r#type .or(existing.as_ref().map(|d| d.r#type.as_str())) .unwrap_or(""), ) .execute(&mut *trans) .await?; debug!( "Attempting to update {} for {username}, {dev:?}, {res:?}", device ); let res = sqlx::query_as!( Device, "SELECT id, caption, type FROM devices WHERE user = ? AND id = ?", username, device ) .fetch_one(&mut *trans) .await?; trans.commit().await?; Ok(Json(res)) } #[derive(Debug, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] pub struct DeviceUpdates<'a> { add: Vec>, remove: Vec>, updates: Vec>, timestamp: Timestamp, } #[get("/updates//?&")] pub fn updates( username: &str, device: DotJson<&str>, since: Option, include_actions: Option, _auth: BasicAuth, ) -> Json> { debug!("Attempting to update {} for {username}, {since:?}", *device); Json(DeviceUpdates { add: vec![], remove: vec![], updates: vec![], timestamp: Timestamp::now(), }) } pub fn routes() -> Vec { routes![get, update, updates] }