1use crate::utils::defaults::DEFAULT_TEXT_ITEM;
24use crate::utils::types::RUMString;
25use axum::extract::State;
26use phf::OrderedMap;
27pub use phf_macros::phf_ordered_map as rumtk_create_const_ordered_map;
28use rumtk_core::types::RUMOrderedMap;
29use rumtk_core::types::{RUMDeserialize, RUMDeserializer, RUMSerialize, RUMSerializer};
30use std::sync::{Arc, RwLock};
31
32pub type TextMap = RUMOrderedMap<RUMString, RUMString>;
33pub type NestedTextMap = RUMOrderedMap<RUMString, TextMap>;
34pub type NestedNestedTextMap = RUMOrderedMap<RUMString, NestedTextMap>;
35pub type RootNestedNestedTextMap = RUMOrderedMap<RUMString, NestedNestedTextMap>;
36
37pub type ConstTextMap = OrderedMap<&'static str, &'static str>;
38pub type ConstNestedTextMap = OrderedMap<&'static str, &'static ConstTextMap>;
39pub type ConstNestedNestedTextMap = OrderedMap<&'static str, &'static ConstNestedTextMap>;
40
41#[derive(RUMSerialize, RUMDeserialize, PartialEq, Debug, Clone, Default)]
42pub struct HeaderConf {
43 pub logo_size: RUMString,
44 pub disable_navlinks: bool,
45 pub disable_logo: bool,
46}
47
48#[derive(RUMSerialize, RUMDeserialize, PartialEq, Debug, Clone, Default)]
49pub struct FooterConf {
50 pub socials_list: RUMString,
51 pub disable_contact_button: bool,
52}
53
54#[derive(RUMSerialize, RUMDeserialize, PartialEq, Debug, Clone, Default)]
62pub struct AppConf {
63 pub title: RUMString,
64 pub description: RUMString,
65 pub company: RUMString,
66 pub copyright: RUMString,
67 pub lang: RUMString,
68 pub theme: RUMString,
69 pub custom_css: bool,
70 pub header_conf: HeaderConf,
71 pub footer_conf: FooterConf,
72
73 strings: RootNestedNestedTextMap,
74 config: NestedNestedTextMap,
75 }
77
78impl AppConf {
79 pub fn update_site_info(
80 &mut self,
81 title: RUMString,
82 description: RUMString,
83 company: RUMString,
84 copyright: RUMString,
85 ) {
86 if !title.is_empty() {
87 self.title = title;
88 }
89 if !company.is_empty() {
90 self.company = company;
91 }
92 if !description.is_empty() {
93 self.description = description;
94 }
95 if !copyright.is_empty() {
96 self.copyright = copyright;
97 }
98 }
99
100 pub fn get_text(&self, item: &str) -> NestedTextMap {
101 match self.strings.get(&self.lang) {
102 Some(l) => match l.get(item) {
103 Some(i) => i.clone(),
104 None => NestedTextMap::default(),
105 },
106 None => NestedTextMap::default(),
107 }
108 }
109
110 pub fn get_conf(&self, section: &str) -> TextMap {
111 match self.config.get(section) {
112 Some(l) => match l.get(&self.lang) {
113 Some(i) => i.clone(),
114 None => match l.get(DEFAULT_TEXT_ITEM) {
115 Some(i) => i.clone(),
116 None => TextMap::default(),
117 },
118 },
119 None => TextMap::default(),
120 }
121 }
122}
123
124pub type SharedAppConf = Arc<RwLock<AppConf>>;
125pub type RouterAppConf = State<Arc<RwLock<AppConf>>>;
126
127#[macro_export]
128macro_rules! rumtk_web_load_conf {
129 ( $args:expr ) => {{
130 rumtk_web_load_conf!($args, "./app.json")
131 }};
132 ( $args:expr, $path:expr ) => {{
133 use rumtk_core::strings::RUMStringConversions;
134 use rumtk_core::{rumtk_deserialize, rumtk_serialize};
135 use std::fs;
136 use std::sync::{Arc, RwLock};
137 use $crate::utils::AppConf;
138
139 let json = match fs::read_to_string($path) {
140 Ok(json) => json,
141 Err(err) => {
142 let json = rumtk_serialize!(AppConf::default(), true)?;
143 fs::write($path, &json);
144 json
145 }
146 };
147
148 let mut conf: AppConf = match rumtk_deserialize!(json) {
149 Ok(conf) => conf,
150 Err(err) => panic!(
151 "The App config file in {} does not meet the expected structure. \
152 See the documentation for more information. Error: {}\n{}",
153 $path, err, json
154 ),
155 };
156 conf.update_site_info(
157 $args.title.clone(),
158 $args.description.clone(),
159 $args.company.clone(),
160 $args.copyright.clone(),
161 );
162 Arc::new(RwLock::new(conf))
163 }};
164}
165
166#[macro_export]
167macro_rules! rumtk_web_get_string {
168 ( $conf:expr, $item:expr ) => {{
169 let owned_state = $conf.read().expect("Lock failure");
170 owned_state.get_text($item)
171 }};
172}
173
174#[macro_export]
175macro_rules! rumtk_web_get_conf {
176 ( $conf:expr, $item:expr ) => {{
177 let owned_state = $conf.read().expect("Lock failure");
178 owned_state.get_conf($item)
179 }};
180}
181
182pub const DEFAULT_TEXT: fn() -> RUMString = || RUMString::default();
186pub const DEFAULT_TEXTMAP: fn() -> TextMap = || TextMap::default();
187pub const DEFAULT_NESTEDTEXTMAP: fn() -> NestedTextMap = || NestedTextMap::default();
188pub const DEFAULT_NESTEDNESTEDTEXTMAP: fn() -> NestedNestedTextMap =
189 || NestedNestedTextMap::default();