use crate::context::ResourceContext;
pub trait Component {
type Context: 'static + Send + Sync;
type Output;
fn render(&self, resources: &ResourceContext) -> Option<Self::Output>;
fn can_render(&self, resources: &ResourceContext) -> bool {
resources.try_get::<Self::Context>().is_some()
}
}
pub trait MultiResourceComponent {
type Output;
fn render_multi(&self, resources: &ResourceContext) -> Option<Self::Output>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::context::ResourceContext;
#[derive(Debug, Clone)]
struct TestContext {
value: u32,
}
struct TestComponent;
impl Component for TestComponent {
type Context = TestContext;
type Output = String;
fn render(&self, resources: &ResourceContext) -> Option<Self::Output> {
let ctx = resources.try_get::<Self::Context>()?;
Some(format!("Value: {}", ctx.value))
}
}
#[test]
fn test_component_render() {
let mut resources = ResourceContext::new();
resources.insert(TestContext { value: 42 });
let component = TestComponent;
let output = component.render(&resources);
assert_eq!(output, Some("Value: 42".to_string()));
}
#[test]
fn test_component_render_missing_resource() {
let resources = ResourceContext::new();
let component = TestComponent;
let output = component.render(&resources);
assert_eq!(output, None);
}
#[test]
fn test_component_can_render() {
let mut resources = ResourceContext::new();
let component = TestComponent;
assert!(!component.can_render(&resources));
resources.insert(TestContext { value: 42 });
assert!(component.can_render(&resources));
}
}