usdpl_front/
lib.rs

1//! Front-end library to be called from Javascript.
2//! Targets WASM.
3//!
4//! In true Javascript tradition, this part of the library does not support error handling.
5//!
6#![warn(missing_docs)]
7
8mod client_handler;
9pub use client_handler::WebSocketHandler;
10mod console_logs;
11mod convert;
12pub mod wasm;
13
14#[allow(missing_docs)]
15pub mod _helpers {
16    pub use js_sys;
17    pub use wasm_bindgen;
18    pub use wasm_bindgen_futures;
19    pub use log;
20    pub use futures;
21    pub use nrpc;
22}
23
24use wasm_bindgen::prelude::*;
25
26#[cfg(feature = "debug")]
27const DEFAULT_MIN_LEVEL: log::Level = log::Level::Trace;
28#[cfg(not(feature = "debug"))]
29const DEFAULT_MIN_LEVEL: log::Level = log::Level::Info;
30
31const DEFAULT_LOGGER: console_logs::BuiltInLogger = console_logs::BuiltInLogger::new(DEFAULT_MIN_LEVEL);
32
33static mut CACHE: Option<std::collections::HashMap<String, JsValue>> = None;
34
35static mut TRANSLATIONS: Option<std::collections::HashMap<String, Vec<String>>> = None;
36
37#[cfg(feature = "encrypt")]
38fn encryption_key() -> Vec<u8> {
39    hex::decode(obfstr::obfstr!(env!("USDPL_ENCRYPTION_KEY"))).unwrap()
40}
41
42static INIT_DONE: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
43
44/// Initialize the front-end library
45//#[wasm_bindgen]
46pub fn init_usdpl() {
47    if !INIT_DONE.swap(true, std::sync::atomic::Ordering::SeqCst) {
48        #[cfg(feature = "console_error_panic_hook")]
49        console_error_panic_hook::set_once();
50
51        log::set_logger(&DEFAULT_LOGGER)
52            .map_err(|e| web_sys::console::error_1(&format!("Failed to setup USDPL logger: {}", e).into()))
53            .unwrap_or(());
54        log::set_max_level(log::LevelFilter::Trace);
55        log::debug!("init_usdpl() log configured");
56
57        unsafe {
58            CACHE = Some(std::collections::HashMap::new());
59        }
60
61        log::info!("USDPL init succeeded: {}", build_info());
62    } else {
63        log::info!("USDPL init was re-attempted");
64    }
65}
66
67fn build_info() -> String {
68    format!("{} v{} ({}) for {} by {}, more: {}",
69        env!("CARGO_PKG_NAME"),
70        env!("CARGO_PKG_VERSION"),
71        env!("CARGO_PKG_LICENSE"),
72        target_usdpl(),
73        env!("CARGO_PKG_AUTHORS"),
74        env!("CARGO_PKG_REPOSITORY"),
75        )
76}
77
78/// Get the targeted plugin framework, or "any" if unknown
79#[wasm_bindgen]
80pub fn target_usdpl() -> String {
81    usdpl_core::api::Platform::current().to_string()
82}
83
84/// Get the UDSPL front-end version
85#[wasm_bindgen]
86pub fn version_usdpl() -> String {
87    env!("CARGO_PKG_VERSION").into()
88}
89
90/// Get the targeted plugin framework, or "any" if unknown
91#[wasm_bindgen]
92pub fn set_value(key: String, value: JsValue) -> JsValue {
93    unsafe {
94        CACHE
95            .as_mut()
96            .unwrap()
97            .insert(key, value)
98            .unwrap_or(JsValue::NULL)
99    }
100}
101
102/// Get the targeted plugin framework, or "any" if unknown
103#[wasm_bindgen]
104pub fn get_value(key: String) -> JsValue {
105    unsafe {
106        CACHE
107            .as_ref()
108            .unwrap()
109            .get(&key)
110            .map(|x| x.to_owned())
111            .unwrap_or(JsValue::UNDEFINED)
112    }
113}
114
115/// Translate a phrase, equivalent to tr_n(msg_id, 0)
116#[wasm_bindgen]
117pub fn tr(msg_id: String) -> String {
118    if let Some(translations) = unsafe { TRANSLATIONS.as_ref().unwrap().get(&msg_id) } {
119        if let Some(translated) = translations.get(0) {
120            translated.to_owned()
121        } else {
122            msg_id
123        }
124    } else {
125        msg_id
126    }
127}
128
129/// Translate a phrase, retrieving the plural form for `n` items
130#[wasm_bindgen]
131pub fn tr_n(msg_id: String, n: usize) -> String {
132    if let Some(translations) = unsafe { TRANSLATIONS.as_ref().unwrap().get(&msg_id) } {
133        if let Some(translated) = translations.get(n) {
134            translated.to_owned()
135        } else {
136            msg_id
137        }
138    } else {
139        msg_id
140    }
141}