use crate::i18n::{AccessibilitySettings, Locale};
use crate::slots::Slots;
use crate::theme::Theme;
#[derive(Clone)]
pub struct RenderContext<'a> {
pub theme: &'a Theme,
pub locale: &'a Locale,
pub accessibility: &'a AccessibilitySettings,
pub slots: &'a Slots,
}
impl<'a> RenderContext<'a> {
pub fn new(theme: &'a Theme, slots: &'a Slots) -> Self {
RenderContext {
theme,
locale: &theme.locale,
accessibility: &theme.accessibility,
slots,
}
}
pub fn with_theme(&self, theme: &'a Theme) -> Self {
RenderContext {
theme,
locale: &theme.locale,
accessibility: &theme.accessibility,
slots: self.slots,
}
}
pub fn with_slots(&self, slots: &'a Slots) -> Self {
RenderContext {
theme: self.theme,
locale: self.locale,
accessibility: self.accessibility,
slots,
}
}
pub fn with_locale(&self, locale: &'a Locale) -> Self {
RenderContext {
theme: self.theme,
locale,
accessibility: self.accessibility,
slots: self.slots,
}
}
pub fn with_accessibility(&self, accessibility: &'a AccessibilitySettings) -> Self {
RenderContext {
theme: self.theme,
locale: self.locale,
accessibility,
slots: self.slots,
}
}
}
pub trait UseTheme {
fn use_theme<'a>(&self, ctx: &'a RenderContext) -> &'a Theme {
ctx.theme
}
fn use_text_direction(&self, ctx: &RenderContext) -> crate::i18n::TextDirection {
ctx.theme.text_direction
}
}
pub trait UseLocale {
fn use_locale<'a>(&self, ctx: &'a RenderContext) -> &'a Locale {
ctx.locale
}
fn use_is_rtl(&self, ctx: &RenderContext) -> bool {
ctx.locale.text_direction.is_rtl()
}
}
pub trait UseAccessibility {
fn use_accessibility<'a>(&self, ctx: &'a RenderContext) -> &'a AccessibilitySettings {
ctx.accessibility
}
fn use_high_contrast(&self, ctx: &RenderContext) -> bool {
ctx.accessibility.high_contrast
}
fn use_font_scale(&self, ctx: &RenderContext) -> f32 {
ctx.accessibility.font_scale
}
fn use_scaled(&self, ctx: &RenderContext, base: u16) -> u16 {
ctx.accessibility.scale_dimension(base)
}
}
impl<T> UseTheme for T {}
impl<T> UseLocale for T {}
impl<T> UseAccessibility for T {}
#[cfg(test)]
mod tests {
use super::*;
use crate::terminal::TerminalCapabilities;
#[test]
fn test_context_creation() {
let caps = TerminalCapabilities::detect();
let theme = Theme::new(caps);
let slots = Slots::new();
let ctx = RenderContext::new(&theme, &slots);
assert_eq!(ctx.theme as *const _, &theme as *const _);
assert_eq!(ctx.locale as *const _, &theme.locale as *const _);
assert_eq!(ctx.slots as *const _, &slots as *const _);
}
#[test]
fn test_hook_traits() {
let caps = TerminalCapabilities::detect();
let theme = Theme::new(caps);
let slots = Slots::new();
let ctx = RenderContext::new(&theme, &slots);
struct TestComponent;
let component = TestComponent;
let theme_from_hook = component.use_theme(&ctx);
assert_eq!(theme_from_hook as *const _, &theme as *const _);
let locale_from_hook = component.use_locale(&ctx);
assert_eq!(locale_from_hook as *const _, &theme.locale as *const _);
}
}