Add Json serialization for context parameters

This commit is contained in:
Manuel Cillero 2024-07-27 22:07:26 +02:00
parent 2c6e9238ab
commit b481d84cba
4 changed files with 50 additions and 41 deletions

View file

@ -66,6 +66,7 @@ static-files = "0.2.3"
pagetop-macros = { version = "0.0", path = "helpers/pagetop-macros" } pagetop-macros = { version = "0.0", path = "helpers/pagetop-macros" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[dependencies.futures] [dependencies.futures]
version = "0.3.30" version = "0.3.30"

View file

@ -47,7 +47,7 @@ impl ComponentTrait for Container {
.join(" "), .join(" "),
); );
cx.set_param::<bool>(PARAM_BASE_INCLUDE_FLEX_ASSETS, true); cx.set_param::<bool>(PARAM_BASE_INCLUDE_FLEX_ASSETS, &true);
} }
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {

View file

@ -19,8 +19,8 @@ impl ComponentTrait for Menu {
} }
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup { fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
cx.set_param::<bool>(PARAM_BASE_INCLUDE_MENU_ASSETS, true); cx.set_param::<bool>(PARAM_BASE_INCLUDE_MENU_ASSETS, &true);
cx.set_param::<bool>(PARAM_BASE_INCLUDE_ICONS, true); cx.set_param::<bool>(PARAM_BASE_INCLUDE_ICONS, &true);
PrepareMarkup::With(html! { PrepareMarkup::With(html! {
div id=[self.id()] class="menu__container" { div id=[self.id()] class="menu__container" {

View file

@ -1,5 +1,4 @@
use crate::base::component::add_base_assets; use crate::base::component::add_base_assets;
use crate::concat_string;
use crate::core::component::AnyOp; use crate::core::component::AnyOp;
use crate::core::theme::all::{theme_by_short_name, THEME_DEFAULT}; use crate::core::theme::all::{theme_by_short_name, THEME_DEFAULT};
use crate::core::theme::{ComponentsInRegions, ThemeRef}; use crate::core::theme::{ComponentsInRegions, ThemeRef};
@ -8,11 +7,16 @@ use crate::html::{Assets, HeadScript, HeadStyles, JavaScript, StyleSheet};
use crate::locale::{LanguageIdentifier, LANGID_DEFAULT}; use crate::locale::{LanguageIdentifier, LANGID_DEFAULT};
use crate::service::HttpRequest; use crate::service::HttpRequest;
use crate::util::TypeInfo; use crate::util::TypeInfo;
use crate::{concat_string, trace};
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json as json;
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::str::FromStr;
pub enum AssetsOp { pub enum AssetsOp {
LangId(&'static LanguageIdentifier), LangId(&'static LanguageIdentifier),
@ -37,7 +41,7 @@ pub enum AssetsOp {
#[derive(Debug)] #[derive(Debug)]
pub enum ParamError { pub enum ParamError {
NotFound, NotFound,
ParseError(String), ParseError(json::Error),
} }
impl fmt::Display for ParamError { impl fmt::Display for ParamError {
@ -62,7 +66,7 @@ pub struct Context {
javascript: Assets<JavaScript>, // JavaScripts. javascript: Assets<JavaScript>, // JavaScripts.
headscript: Assets<HeadScript>, // Scripts in head. headscript: Assets<HeadScript>, // Scripts in head.
regions : ComponentsInRegions, regions : ComponentsInRegions,
params : HashMap<&'static str, String>, params : HashMap<&'static str, json::Value>,
id_counter: usize, id_counter: usize,
} }
@ -79,7 +83,7 @@ impl Context {
javascript: Assets::<JavaScript>::new(), // JavaScripts. javascript: Assets::<JavaScript>::new(), // JavaScripts.
headscript: Assets::<HeadScript>::new(), // Scripts in head. headscript: Assets::<HeadScript>::new(), // Scripts in head.
regions : ComponentsInRegions::default(), regions : ComponentsInRegions::default(),
params : HashMap::<&str, String>::new(), params : HashMap::<&str, json::Value>::new(),
id_counter: 0, id_counter: 0,
} }
} }
@ -121,17 +125,17 @@ impl Context {
self self
} }
pub fn set_param<T: FromStr + ToString>(&mut self, key: &'static str, value: T) -> &mut Self { pub fn set_param<T: Serialize>(&mut self, key: &'static str, value: &T) -> &mut Self {
self.params.insert(key, value.to_string()); json::to_value(value).map_or_else(
|e| trace::error!("Serialization failed for param {key}: {e}"),
|v| {
self.params.insert(key, v);
},
);
self self
} }
pub fn remove_param(&mut self, key: &'static str) -> &mut Self { // Context GETTERS.
self.params.remove(key);
self
}
/// Context GETTERS.
pub fn request(&self) -> &HttpRequest { pub fn request(&self) -> &HttpRequest {
&self.request &self.request
@ -153,14 +157,14 @@ impl Context {
&self.regions &self.regions
} }
pub fn get_param<T: FromStr + ToString>(&self, key: &'static str) -> Result<T, ParamError> { pub fn get_param<T: DeserializeOwned>(&self, key: &'static str) -> Result<T, ParamError> {
match self.params.get(key) { self.params
Some(value) => T::from_str(value).map_err(|_| ParamError::ParseError(value.clone())), .get(key)
None => Err(ParamError::NotFound), .ok_or(ParamError::NotFound)
} .and_then(|v| json::from_value(v.clone()).map_err(ParamError::ParseError))
} }
/// Context PREPARE. // Context PREPARE.
pub(crate) fn prepare_assets(&mut self) -> Markup { pub(crate) fn prepare_assets(&mut self) -> Markup {
html! { html! {
@ -179,6 +183,10 @@ impl Context {
// Context EXTRAS. // Context EXTRAS.
pub fn remove_param(&mut self, key: &'static str) -> bool {
self.params.remove(key).is_some()
}
pub fn required_id<T>(&mut self, id: Option<String>) -> String { pub fn required_id<T>(&mut self, id: Option<String>) -> String {
if let Some(id) = id { if let Some(id) = id {
id id