nestforge_core/
injectable.rs1use anyhow::Result;
2
3use crate::{framework_log_event, Container};
4
5pub trait IntoInjectableResult<T> {
6 fn into_injectable_result(self) -> Result<T>;
7}
8
9impl<T> IntoInjectableResult<T> for T {
10 fn into_injectable_result(self) -> Result<T> {
11 Ok(self)
12 }
13}
14
15impl<T> IntoInjectableResult<T> for Result<T> {
16 fn into_injectable_result(self) -> Result<T> {
17 self
18 }
19}
20
21pub trait Injectable: Send + Sync + 'static {
47 fn register(container: &Container) -> anyhow::Result<()>;
50}
51
52pub fn register_injectable<T>(container: &Container) -> Result<()>
53where
54 T: Injectable,
55{
56 framework_log_event(
57 "injectable_register",
58 &[("type", std::any::type_name::<T>().to_string())],
59 );
60 T::register(container)
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[derive(Default)]
68 struct DefaultService;
69
70 impl Injectable for DefaultService {
71 fn register(container: &Container) -> Result<()> {
72 container.register(Self)?;
73 Ok(())
74 }
75 }
76
77 struct FactoryService(&'static str);
78
79 impl Injectable for FactoryService {
80 fn register(container: &Container) -> Result<()> {
81 let value: FactoryService =
82 Result::<FactoryService>::Ok(FactoryService("ready")).into_injectable_result()?;
83 container.register(value)?;
84 Ok(())
85 }
86 }
87
88 #[test]
89 fn register_injectable_stores_service_in_container() {
90 let container = Container::new();
91
92 register_injectable::<DefaultService>(&container).expect("injectable should register");
93
94 assert!(container.resolve::<DefaultService>().is_ok());
95 }
96
97 #[test]
98 fn into_injectable_result_accepts_plain_values() {
99 let value = FactoryService("plain")
100 .into_injectable_result()
101 .expect("plain value should convert");
102
103 assert_eq!(value.0, "plain");
104 }
105
106 #[test]
107 fn into_injectable_result_accepts_anyhow_results() {
108 let container = Container::new();
109
110 register_injectable::<FactoryService>(&container).expect("factory should register");
111
112 let service = container
113 .resolve::<FactoryService>()
114 .expect("factory service should resolve");
115 assert_eq!(service.0, "ready");
116 }
117}