Skip to main content

cache_manager/
cache_module.rs

1//! Port map for upstream `lib/cache.module.ts`.
2
3use serde::{Deserialize, Serialize};
4
5use crate::cache_constants::CACHE_MANAGER;
6use crate::cache_providers::createCacheManager;
7use crate::interfaces::{CacheModuleAsyncOptions, CacheModuleOptions, CacheOptions};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub enum ProviderKind {
11    Class,
12    Value,
13    Factory,
14    Existing,
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub struct Provider {
19    pub provide: String,
20    pub kind: ProviderKind,
21    pub use_value: Option<serde_json::Value>,
22    pub inject: Vec<String>,
23    pub use_existing: Option<String>,
24}
25
26impl Provider {
27    pub fn class(provide: impl Into<String>) -> Self {
28        Self {
29            provide: provide.into(),
30            kind: ProviderKind::Class,
31            use_value: None,
32            inject: Vec::new(),
33            use_existing: None,
34        }
35    }
36
37    pub fn value<T: Serialize>(provide: impl Into<String>, value: T) -> Self {
38        Self {
39            provide: provide.into(),
40            kind: ProviderKind::Value,
41            use_value: serde_json::to_value(value).ok(),
42            inject: Vec::new(),
43            use_existing: None,
44        }
45    }
46
47    pub fn factory(provide: impl Into<String>, inject: Vec<String>) -> Self {
48        Self {
49            provide: provide.into(),
50            kind: ProviderKind::Factory,
51            use_value: None,
52            inject,
53            use_existing: None,
54        }
55    }
56
57    pub fn existing(provide: impl Into<String>, use_existing: impl Into<String>) -> Self {
58        Self {
59            provide: provide.into(),
60            kind: ProviderKind::Existing,
61            use_value: None,
62            inject: Vec::new(),
63            use_existing: Some(use_existing.into()),
64        }
65    }
66}
67
68#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
69pub struct DynamicModule {
70    pub global: bool,
71    pub module: String,
72    pub imports: Vec<String>,
73    pub providers: Vec<Provider>,
74    pub exports: Vec<String>,
75}
76
77impl DynamicModule {
78    pub fn cache_options(&self) -> Option<CacheOptions> {
79        self.providers
80            .iter()
81            .find(|provider| provider.provide == crate::cache_constants::CACHE_MODULE_OPTIONS)
82            .and_then(|provider| provider.use_value.as_ref())
83            .and_then(|value| serde_json::from_value(value.clone()).ok())
84    }
85}
86
87pub struct Cache;
88
89pub struct CacheModule;
90
91impl CacheModule {
92    pub fn register(options: CacheModuleOptions) -> DynamicModule {
93        DynamicModule {
94            global: options.isGlobal.unwrap_or(false),
95            module: "CacheModule".to_string(),
96            imports: Vec::new(),
97            providers: vec![
98                Provider::value(
99                    crate::cache_constants::CACHE_MODULE_OPTIONS,
100                    &options.cache_options,
101                ),
102                createCacheManager(),
103                Provider::existing("Cache", CACHE_MANAGER),
104            ],
105            exports: vec![CACHE_MANAGER.to_string(), "Cache".to_string()],
106        }
107    }
108
109    pub fn registerAsync(options: CacheModuleAsyncOptions) -> DynamicModule {
110        let mut providers = Self::createAsyncProviders(options.clone());
111        providers.push(createCacheManager());
112        providers.push(Provider::existing("Cache", CACHE_MANAGER));
113        providers.extend(options.extraProviders.iter().map(Provider::class));
114
115        DynamicModule {
116            global: options.isGlobal.unwrap_or(false),
117            module: "CacheModule".to_string(),
118            imports: options.imports,
119            providers,
120            exports: vec![CACHE_MANAGER.to_string(), "Cache".to_string()],
121        }
122    }
123
124    pub fn register_async(options: CacheModuleAsyncOptions) -> DynamicModule {
125        Self::registerAsync(options)
126    }
127
128    fn createAsyncProviders(options: CacheModuleAsyncOptions) -> Vec<Provider> {
129        if options.useExisting.is_some() || options.useFactory {
130            return vec![Self::createAsyncOptionsProvider(options)];
131        }
132
133        let use_class = options.useClass.clone().unwrap_or_default();
134        vec![
135            Self::createAsyncOptionsProvider(options),
136            Provider::class(use_class),
137        ]
138    }
139
140    fn createAsyncOptionsProvider(options: CacheModuleAsyncOptions) -> Provider {
141        if options.useFactory {
142            return Provider::factory(crate::cache_constants::CACHE_MODULE_OPTIONS, options.inject);
143        }
144
145        Provider::factory(
146            crate::cache_constants::CACHE_MODULE_OPTIONS,
147            vec![
148                options
149                    .useExisting
150                    .unwrap_or_else(|| options.useClass.unwrap_or_default()),
151            ],
152        )
153    }
154}