use std::cell::RefCell;
use std::rc::Rc;
pub trait AppInfo {
fn version_name(&self) -> Option<String>;
fn build_version(&self) -> Option<String>;
}
pub type AppInfoRef = Rc<dyn AppInfo>;
struct DefaultAppInfo;
impl AppInfo for DefaultAppInfo {
fn version_name(&self) -> Option<String> {
None
}
fn build_version(&self) -> Option<String> {
None
}
}
thread_local! {
static PLATFORM_APP_INFO: RefCell<Option<AppInfoRef>> = const { RefCell::new(None) };
}
pub fn set_platform_app_info(info: AppInfoRef) {
PLATFORM_APP_INFO.with(|cell| *cell.borrow_mut() = Some(info));
}
pub fn clear_platform_app_info() {
PLATFORM_APP_INFO.with(|cell| *cell.borrow_mut() = None);
}
pub fn app_info() -> AppInfoRef {
PLATFORM_APP_INFO
.with(|cell| cell.borrow().clone())
.unwrap_or_else(|| Rc::new(DefaultAppInfo))
}
pub fn version_name() -> Option<String> {
app_info().version_name()
}
pub fn build_version() -> Option<String> {
app_info().build_version()
}
#[cfg(test)]
mod tests {
use super::*;
struct Packaged;
impl AppInfo for Packaged {
fn version_name(&self) -> Option<String> {
Some("1.4.2-debug".to_string())
}
fn build_version(&self) -> Option<String> {
Some("17.2.1".to_string())
}
}
#[test]
fn an_unpackaged_binary_has_no_version_to_report() {
clear_platform_app_info();
assert_eq!(version_name(), None);
assert_eq!(build_version(), None);
}
#[test]
fn the_platform_answer_wins_and_carries_what_packaging_added() {
clear_platform_app_info();
set_platform_app_info(Rc::new(Packaged));
assert_eq!(version_name().as_deref(), Some("1.4.2-debug"));
assert_eq!(build_version().as_deref(), Some("17.2.1"));
clear_platform_app_info();
assert_eq!(version_name(), None);
}
}