#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
#![warn(missing_docs, rust_2018_idioms, future_incompatible, keyword_idents)]
pub mod error;
mod integration;
mod platform;
mod theme;
use error::Error;
use async_stream::stream;
use futures_core::stream::Stream;
use std::hash::Hash;
use uuid::Uuid;
#[doc(inline)]
pub use theme::{Theme, ThemeColor, ThemeContrast, ThemeKind, ThemePalette, ThemeScheme};
pub struct SystemTheme {
platform: platform::Platform,
identifier: Uuid,
}
impl Hash for SystemTheme {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.identifier.hash(state);
}
}
impl SystemTheme {
pub fn new() -> Result<Self, Error> {
Ok(Self {
platform: platform::Platform::new()?,
identifier: Uuid::new_v4(),
})
}
pub fn get_kind(&self) -> Result<ThemeKind, Error> {
self.platform.theme_kind()
}
pub fn get_scheme(&self) -> Result<ThemeScheme, Error> {
self.platform.theme_scheme()
}
pub fn get_contrast(&self) -> Result<ThemeContrast, Error> {
self.platform.theme_contrast()
}
pub fn get_accent(&self) -> Result<ThemeColor, Error> {
self.platform.theme_accent()
}
pub fn get_theme(&self) -> Theme {
let kind = self.get_kind().unwrap_or_default();
let scheme = self.get_scheme().unwrap_or_default();
let contrast = self.get_contrast().unwrap_or_default();
Theme::new(kind, scheme, contrast, self.get_accent().ok())
}
pub fn subscribe(&self) -> impl Stream<Item = ()> {
let notify = self.platform.get_notify();
stream! {
let mut notified = notify.notified();
loop {
notified.await;
notified = notify.notified();
yield ();
}
}
}
}