diff --git a/Cargo.toml b/Cargo.toml index 6d699b7..8dd5973 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diary_app_rust" -version = "0.10.8" +version = "0.10.9" authors = ["Daniel Boline "] edition = "2018" @@ -22,7 +22,7 @@ diary_app_bot = {path="diary_app_bot"} dirs = "5.0" env_logger = {version="0.11", features=["color", "humantime", "regex"], default_features = false} time = {version="0.3", features=["serde-human-readable", "macros", "formatting"]} -tokio = {version="1.35", features=["rt", "macros", "rt-multi-thread"]} +tokio = {version="1.37", features=["rt", "macros", "rt-multi-thread"]} [workspace] members = [ diff --git a/diary_app_api/Cargo.toml b/diary_app_api/Cargo.toml index 39edde7..3c9781b 100644 --- a/diary_app_api/Cargo.toml +++ b/diary_app_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diary_app_api" -version = "0.10.8" +version = "0.10.9" authors = ["Daniel Boline "] edition = "2018" @@ -9,11 +9,12 @@ edition = "2018" [dependencies] anyhow = "1.0" async-trait = "0.1" -authorized_users = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.12"} +authorized_users = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.13"} aws-config = {version="1.1", features=["behavior-version-latest"]} diary_app_lib = {path = "../diary_app_lib"} -dioxus = "0.4" -dioxus-ssr = "0.4" +dioxus = "0.5" +dioxus-core = "0.5" +dioxus-ssr = "0.5" derive_more = "0.99" futures = "0.3" handlebars = "5.1" @@ -21,22 +22,22 @@ itertools = "0.12" log = "0.4" maplit = "1.0" parking_lot = "0.12" -postgres_query = {git = "https://github.com/ddboline/rust-postgres-query", tag = "0.3.6", features=["deadpool"]} -rweb = {git = "https://github.com/ddboline/rweb.git", features=["openapi"], default-features=false, tag="0.15.1-1"} -rweb-helper = { git = "https://github.com/ddboline/rweb_helper.git", tag="0.5.1" } +postgres_query = {git = "https://github.com/ddboline/rust-postgres-query", tag = "0.3.7", features=["deadpool"]} +rweb = {git = "https://github.com/ddboline/rweb.git", features=["openapi"], default-features=false, tag="0.15.2"} +rweb-helper = { git = "https://github.com/ddboline/rweb_helper.git", tag="0.5.3" } serde = "1.0" serde_derive = "1.0" serde_json = "1.0" serde_yaml = "0.9" -stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types", "rweb-openapi"], tag="0.9.2" } +stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types", "rweb-openapi"], tag="0.9.3" } thiserror = "1.0" time = {version="0.3", features=["serde-human-readable", "macros", "formatting"]} time-tz = {version="2.0", features=["system"]} -tokio = {version="1.36", features=["time"]} +tokio = {version="1.37", features=["time"]} uuid = "1.0" [dev-dependencies] -auth_server_http = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.12"} -auth_server_lib = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.12"} +auth_server_http = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.13"} +auth_server_lib = { git = "https://github.com/ddboline/auth_server_rust.git", tag="0.11.13"} env_logger = {version="0.11", features=["color", "humantime", "regex"], default_features = false} -reqwest = {version="0.11", features=["cookies", "json", "rustls-tls", "stream"]} +reqwest = {version="0.12", features=["cookies", "json", "rustls-tls", "stream"]} diff --git a/diary_app_api/src/elements.rs b/diary_app_api/src/elements.rs index 074f89c..ea46b72 100644 --- a/diary_app_api/src/elements.rs +++ b/diary_app_api/src/elements.rs @@ -1,6 +1,5 @@ use dioxus::prelude::{ - component, dioxus_elements, rsx, Element, GlobalAttributes, IntoDynNode, Props, Scope, - VirtualDom, + component, dioxus_elements, rsx, Element, GlobalAttributes, IntoDynNode, Props, VirtualDom, }; use rweb_helper::DateType; use stack_string::StackString; @@ -10,15 +9,24 @@ use time_tz::OffsetDateTimeExt; use diary_app_lib::{date_time_wrapper::DateTimeWrapper, models::DiaryConflict}; -pub fn index_body() -> String { +use crate::errors::ServiceError as Error; + +/// # Errors +/// Returns error if formatting fails +pub fn index_body() -> Result { let mut app = VirtualDom::new(IndexElement); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] -fn IndexElement(cx: Scope) -> Element { - cx.render(rsx! { +fn IndexElement() -> Element { + rsx! { head { style { dangerous_inner_html: include_str!("../../templates/style.css") @@ -79,14 +87,16 @@ fn IndexElement(cx: Scope) -> Element { dangerous_inner_html: include_str!("../../templates/scripts.js") } } - }) + } } +/// # Errors +/// Returns error if formatting fails pub fn list_body( conflicts: HashSet, dates: Vec, start: Option, -) -> String { +) -> Result { let mut app = VirtualDom::new_with_props( DateListElement, DateListElementProps { @@ -95,13 +105,17 @@ pub fn list_body( start, }, ); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] fn DateListElement( - cx: Scope, conflicts: HashSet, dates: Vec, start: Option, @@ -128,8 +142,8 @@ fn DateListElement( } } }; - cx.render(rsx! { - dates.iter().enumerate().map(|(idx, t)| { + rsx! { + {dates.iter().enumerate().map(|(idx, t)| { let d: Date = (*t).into(); let c = if conflicts.contains(t) { Some(rsx! { @@ -151,37 +165,43 @@ fn DateListElement( name: "{d}", value: "{d}", "onclick": "switchToDate( '{d}' )", - c + {c} }, br {}, } } - }) - buttons, - }) + })}, + {buttons}, + } } -pub fn list_conflicts_body(date: Option, conflicts: Vec) -> String { +/// # Errors +/// Returns error if formatting fails +pub fn list_conflicts_body( + date: Option, + conflicts: Vec, +) -> Result { let mut app = VirtualDom::new_with_props( ListConflictsElement, ListConflictsElementProps { date, conflicts }, ); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] -fn ListConflictsElement( - cx: Scope, - date: Option, - conflicts: Vec, -) -> Element { +fn ListConflictsElement(date: Option, conflicts: Vec) -> Element { let local = DateTimeWrapper::local_tz(); let clean_conflicts = if let Some(date) = date { if conflicts.is_empty() { None } else { - let date: Date = (*date).into(); + let date: Date = (date).into(); Some(rsx! { button { "type": "submit", @@ -193,8 +213,8 @@ fn ListConflictsElement( } else { None }; - cx.render(rsx! { - conflicts.iter().enumerate().map(|(idx, t)| { + rsx! { + {conflicts.iter().enumerate().map(|(idx, t)| { let d: Date = date.unwrap_or_else(|| OffsetDateTime::now_utc().to_timezone(local).date().into()).into(); rsx! { input { @@ -205,28 +225,35 @@ fn ListConflictsElement( "onclick": "showConflict( '{d}', '{t}' )", } } - }), + })}, br { - clean_conflicts, + {clean_conflicts}, button { "type": "submit", "onclick": "switchToList()", "List", }, }, - }) + } } -pub fn search_body(results: Vec) -> String { +/// # Errors +/// Returns error if formatting fails +pub fn search_body(results: Vec) -> Result { let mut app = VirtualDom::new_with_props(SearchElement, SearchElementProps { results }); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] -fn SearchElement(cx: Scope, results: Vec) -> Element { +fn SearchElement(results: Vec) -> Element { let body = results.join("\n"); - cx.render(rsx! { + rsx! { textarea { "autofocus": "true", readonly: "readonly", @@ -236,10 +263,12 @@ fn SearchElement(cx: Scope, results: Vec) -> Element { "cols": "100", "{body}", } - }) + } } -pub fn edit_body(date: Date, text: Vec, edit_button: bool) -> String { +/// # Errors +/// Returns error if formatting fails +pub fn edit_body(date: Date, text: Vec, edit_button: bool) -> Result { let mut app = VirtualDom::new_with_props( EditElement, EditElementProps { @@ -248,14 +277,19 @@ pub fn edit_body(date: Date, text: Vec, edit_button: bool) -> Strin edit_button, }, ); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] -fn EditElement(cx: Scope, date: Date, text: Vec, edit_button: bool) -> Element { +fn EditElement(date: Date, text: Vec, edit_button: bool) -> Element { let text = text.join("\n"); - let buttons = if *edit_button { + let buttons = if edit_button { rsx! { input { "type": "button", @@ -283,7 +317,7 @@ fn EditElement(cx: Scope, date: Date, text: Vec, edit_button: bool) } } }; - let textarea = if *edit_button { + let textarea = if edit_button { rsx! { textarea { name: "message", @@ -307,19 +341,21 @@ fn EditElement(cx: Scope, date: Date, text: Vec, edit_button: bool) } } }; - cx.render(rsx! { - textarea, + rsx! { + {textarea}, br { - buttons + {buttons} } - }) + } } +/// # Errors +/// Returns error if formatting fails pub fn show_conflict_body( date: Date, conflicts: Vec, datetime: DateTimeWrapper, -) -> String { +) -> Result { let mut app = VirtualDom::new_with_props( ShowConflictElement, ShowConflictElementProps { @@ -328,13 +364,17 @@ pub fn show_conflict_body( datetime, }, ); - drop(app.rebuild()); - dioxus_ssr::render(&app) + app.rebuild_in_place(); + let mut renderer = dioxus_ssr::Renderer::default(); + let mut buffer = String::new(); + renderer + .render_to(&mut buffer, &app) + .map_err(Into::::into)?; + Ok(buffer) } #[component] fn ShowConflictElement( - cx: Scope, date: Date, conflicts: Vec, datetime: DateTimeWrapper, @@ -411,9 +451,9 @@ fn ShowConflictElement( "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]Z" )) .unwrap_or_else(|_| String::new()); - cx.render(rsx! { + rsx! { div { - conflict_text.into_iter(), + {conflict_text.into_iter()}, } input { "type": "button", @@ -439,5 +479,5 @@ fn ShowConflictElement( value: "Edit", "onclick": "switchToEditor('{date}')", }, - }) + } } diff --git a/diary_app_api/src/errors.rs b/diary_app_api/src/errors.rs index d1a00fa..aaac467 100644 --- a/diary_app_api/src/errors.rs +++ b/diary_app_api/src/errors.rs @@ -11,7 +11,11 @@ use rweb::{ Rejection, Reply, }; use serde::Serialize; -use std::{borrow::Cow, convert::Infallible, fmt::Debug}; +use std::{ + borrow::Cow, + convert::Infallible, + fmt::{Debug, Error as FmtError}, +}; use thiserror::Error; use crate::logged_user::TRIGGER_DB_UPDATE; @@ -30,6 +34,8 @@ pub enum ServiceError { RenderError(#[from] RenderError), #[error("PqError {0}")] PqError(#[from] PqError), + #[error("FmtError {0}")] + FmtError(#[from] FmtError), } impl Reject for ServiceError {} diff --git a/diary_app_api/src/routes.rs b/diary_app_api/src/routes.rs index 6a646c5..6559293 100644 --- a/diary_app_api/src/routes.rs +++ b/diary_app_api/src/routes.rs @@ -38,7 +38,7 @@ pub async fn search( ) -> WarpResult { let query = query.into_inner(); let results = search_results(query, state).await?; - let body = search_body(results).into(); + let body = search_body(results)?.into(); Ok(HtmlBase::new(body).into()) } @@ -101,7 +101,7 @@ pub async fn sync( #[data] state: AppState, ) -> WarpResult { let results = sync_body(state).await?; - let body = search_body(results).into(); + let body = search_body(results)?.into(); Ok(HtmlBase::new(body).into()) } @@ -182,7 +182,7 @@ async fn get_body(query: ListOptions, state: &AppState) -> HttpResult HttpResult HttpResult); pub async fn diary_frontpage( #[filter = "LoggedUser::filter"] _: LoggedUser, ) -> WarpResult { - let body = index_body().into(); + let body = index_body()?.into(); Ok(HtmlBase::new(body).into()) } @@ -298,7 +298,7 @@ async fn get_conflicts_body(query: ConflictData, state: AppState) -> HttpResult< } else { Vec::new() }; - let body = list_conflicts_body(query.date, conflicts).into(); + let body = list_conflicts_body(query.date, conflicts)?.into(); Ok(body) } @@ -336,7 +336,7 @@ async fn get_show_conflict(query: ConflictData, state: AppState) -> HttpResult"] edition = "2018" @@ -16,7 +16,7 @@ futures = "0.3" log = "0.4" once_cell = "1.0" parking_lot = "0.12" -stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types"], tag="0.9.2" } +stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types"], tag="0.9.3" } thiserror = "1.0" -tokio = {version="1.36", features=["rt", "macros", "rt-multi-thread"]} +tokio = {version="1.37", features=["rt", "macros", "rt-multi-thread"]} telegram-bot = {git = "https://github.com/ddboline/telegram-bot.git", tag="0.9.0-4", default_features=false} diff --git a/diary_app_lib/Cargo.toml b/diary_app_lib/Cargo.toml index 4aa8283..34ba881 100644 --- a/diary_app_lib/Cargo.toml +++ b/diary_app_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diary_app_lib" -version = "0.10.8" +version = "0.10.9" authors = ["Daniel Boline "] edition = "2018" @@ -13,8 +13,8 @@ clap = {version="4.0", features=["derive"]} crossbeam-channel = "0.5" crossbeam-utils = "0.8" deadqueue = "0.2" -deadpool = { version = "0.10", features=["serde", "rt_tokio_1"] } -deadpool-postgres = { version = "0.12", features=["serde"] } +deadpool = { version = "0.11", features=["serde", "rt_tokio_1"] } +deadpool-postgres = { version = "0.13", features=["serde"] } derive_more = "0.99" difference = "2.0" dirs = "5.0" @@ -26,7 +26,7 @@ log = "0.4" once_cell = "1.0" parking_lot = "0.12" postgres-types = "0.2" -postgres_query = {git = "https://github.com/ddboline/rust-postgres-query", tag = "0.3.6", features=["deadpool"]} +postgres_query = {git = "https://github.com/ddboline/rust-postgres-query", tag = "0.3.7", features=["deadpool"]} rand = "0.8" rayon = "1.5" refinery = {version="0.8", features=["tokio-postgres"]} @@ -35,12 +35,12 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" smallvec = "1.6" -stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types"], tag="0.9.2" } +stack-string = { git = "https://github.com/ddboline/stack-string-rs.git", features=["postgres_types"], tag="0.9.3" } stdout-channel = "0.6" thiserror = "1.0" time = {version="0.3", features=["serde-human-readable", "macros", "formatting"]} time-tz = {version="2.0", features=["system"]} -tokio = {version="1.35", features=["rt", "macros", "rt-multi-thread"]} +tokio = {version="1.37", features=["rt", "macros", "rt-multi-thread"]} tokio-postgres = {version = "0.7", features = ["with-time-0_3", "with-uuid-1", "with-serde_json-1"]} url = "2.3" uuid = "1.0" diff --git a/src/telegram_bot.rs b/src/telegram_bot.rs index c8b0ad3..ffe87d3 100644 --- a/src/telegram_bot.rs +++ b/src/telegram_bot.rs @@ -5,5 +5,5 @@ use diary_app_bot::telegram_bot::run_bot; #[tokio::main] async fn main() { env_logger::init(); - run_bot().await.unwrap(); + Box::pin(run_bot()).await.unwrap(); }