1use std::ops::{Deref, DerefMut};
2
3use crate::{
4 AppContext, AppError, ComponentMut, ComponentRef, Dependencies, Service, ServiceDependencyExt,
5};
6
7pub trait Extract<T> {
9 fn extract(ctx: &AppContext) -> Result<T, AppError>;
10
11 fn dependencies() -> Dependencies {
12 Dependencies::new()
13 }
14}
15
16pub trait ExtractRef<T> {
22 type Ref<'a>: Deref<Target = T> + 'a;
23
24 fn extract_ref(ctx: &AppContext) -> Result<Self::Ref<'_>, AppError>;
25
26 fn dependencies() -> Dependencies {
27 Dependencies::new()
28 }
29}
30
31pub trait ExtractMut<T>: ExtractRef<T> {
58 type RefMut<'a>: DerefMut<Target = T> + 'a;
59
60 fn extract_mut(ctx: &AppContext) -> Result<Self::RefMut<'_>, AppError>;
61}
62
63impl<T, S> Extract<T> for S
64where
65 T: Clone + Send + Sync + 'static,
66 S: Service<Handle = T> + 'static,
67{
68 fn extract(ctx: &AppContext) -> Result<T, AppError> {
69 ctx.get_component::<T>().ok_or(AppError::MissingComponent(std::any::type_name::<T>()))
70 }
71
72 fn dependencies() -> Dependencies {
73 Dependencies::new().service::<S>()
74 }
75}
76
77impl<T, S> ExtractRef<T> for S
78where
79 T: Send + Sync + 'static,
80 S: Service<Handle = T> + 'static,
81{
82 type Ref<'a> = ComponentRef<'a, T>;
83
84 fn extract_ref(ctx: &AppContext) -> Result<Self::Ref<'_>, AppError> {
85 ctx.get_component_ref::<T>().ok_or(AppError::MissingComponent(std::any::type_name::<T>()))
86 }
87
88 fn dependencies() -> Dependencies {
89 Dependencies::new().service::<S>()
90 }
91}
92
93impl ExtractRef<AppContext> for AppContext {
94 type Ref<'a> = &'a AppContext;
95
96 fn extract_ref(ctx: &AppContext) -> Result<&AppContext, AppError> {
97 Ok(ctx)
98 }
99}
100
101pub struct Component;
103
104impl<T> Extract<T> for Component
105where
106 T: Clone + Send + Sync + 'static,
107{
108 fn extract(ctx: &AppContext) -> Result<T, AppError> {
109 ctx.get_component::<T>().ok_or(AppError::MissingComponent(std::any::type_name::<T>()))
110 }
111}
112
113impl<T> ExtractRef<T> for Component
114where
115 T: Send + Sync + 'static,
116{
117 type Ref<'a> = ComponentRef<'a, T>;
118
119 fn extract_ref(ctx: &AppContext) -> Result<Self::Ref<'_>, AppError> {
120 ctx.get_component_ref::<T>()
121 .ok_or(AppError::MissingComponent(std::any::type_name::<T>()))
122 }
123}
124
125impl<T> ExtractMut<T> for Component
126where
127 T: Send + Sync + 'static,
128{
129 type RefMut<'a> = ComponentMut<'a, T>;
130
131 fn extract_mut(ctx: &AppContext) -> Result<Self::RefMut<'_>, AppError> {
132 ctx.get_component_mut::<T>()
133 .ok_or(AppError::MissingComponent(std::any::type_name::<T>()))
134 }
135}