Skip to main content

rustauth_plugins/anonymous/
options.rs

1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use rustauth_core::error::RustAuthError;
6
7use super::hooks::AnonymousLinkAccount;
8
9pub type AnonymousOptionFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
10pub type GenerateRandomEmail = Arc<dyn Fn() -> AnonymousOptionFuture<String> + Send + Sync>;
11pub type GenerateName = Arc<dyn Fn() -> AnonymousOptionFuture<String> + Send + Sync>;
12pub type OnLinkAccount = Arc<
13    dyn Fn(AnonymousLinkAccount) -> AnonymousOptionFuture<Result<(), RustAuthError>> + Send + Sync,
14>;
15
16#[derive(Clone, Default)]
17pub struct AnonymousOptions {
18    pub email_domain_name: Option<String>,
19    pub generate_random_email: Option<GenerateRandomEmail>,
20    pub generate_name: Option<GenerateName>,
21    pub disable_delete_anonymous_user: bool,
22    pub on_link_account: Option<OnLinkAccount>,
23    pub field_name: Option<String>,
24}
25
26impl AnonymousOptions {
27    #[must_use]
28    pub fn builder() -> AnonymousOptionsBuilder {
29        AnonymousOptionsBuilder::default()
30    }
31
32    pub(crate) fn storage_field_name(&self) -> &str {
33        self.field_name.as_deref().unwrap_or("is_anonymous")
34    }
35
36    #[must_use]
37    pub fn email_domain_name(mut self, domain: impl Into<String>) -> Self {
38        self.email_domain_name = Some(domain.into());
39        self
40    }
41
42    #[must_use]
43    pub fn generate_random_email<F>(mut self, generator: F) -> Self
44    where
45        F: Fn() -> String + Send + Sync + 'static,
46    {
47        self.generate_random_email = Some(Arc::new(move || {
48            let value = generator();
49            Box::pin(std::future::ready(value))
50        }));
51        self
52    }
53
54    #[must_use]
55    pub fn generate_random_email_async<F, Fut>(mut self, generator: F) -> Self
56    where
57        F: Fn() -> Fut + Send + Sync + 'static,
58        Fut: Future<Output = String> + Send + 'static,
59    {
60        self.generate_random_email = Some(Arc::new(move || Box::pin(generator())));
61        self
62    }
63
64    #[must_use]
65    pub fn generate_name<F>(mut self, generator: F) -> Self
66    where
67        F: Fn() -> String + Send + Sync + 'static,
68    {
69        self.generate_name = Some(Arc::new(move || {
70            let value = generator();
71            Box::pin(std::future::ready(value))
72        }));
73        self
74    }
75
76    #[must_use]
77    pub fn generate_name_async<F, Fut>(mut self, generator: F) -> Self
78    where
79        F: Fn() -> Fut + Send + Sync + 'static,
80        Fut: Future<Output = String> + Send + 'static,
81    {
82        self.generate_name = Some(Arc::new(move || Box::pin(generator())));
83        self
84    }
85
86    #[must_use]
87    pub fn disable_delete_anonymous_user(mut self, disabled: bool) -> Self {
88        self.disable_delete_anonymous_user = disabled;
89        self
90    }
91
92    #[must_use]
93    pub fn on_link_account<F>(mut self, callback: F) -> Self
94    where
95        F: Fn(AnonymousLinkAccount) -> Result<(), RustAuthError> + Send + Sync + 'static,
96    {
97        self.on_link_account = Some(Arc::new(move |data| {
98            let result = callback(data);
99            Box::pin(std::future::ready(result))
100        }));
101        self
102    }
103
104    #[must_use]
105    pub fn on_link_account_async<F, Fut>(mut self, callback: F) -> Self
106    where
107        F: Fn(AnonymousLinkAccount) -> Fut + Send + Sync + 'static,
108        Fut: Future<Output = Result<(), RustAuthError>> + Send + 'static,
109    {
110        self.on_link_account = Some(Arc::new(move |data| Box::pin(callback(data))));
111        self
112    }
113
114    #[must_use]
115    pub fn field_name(mut self, field_name: impl Into<String>) -> Self {
116        self.field_name = Some(field_name.into());
117        self
118    }
119}
120
121#[derive(Clone, Default)]
122pub struct AnonymousOptionsBuilder {
123    email_domain_name: Option<String>,
124    generate_random_email: Option<GenerateRandomEmail>,
125    generate_name: Option<GenerateName>,
126    disable_delete_anonymous_user: Option<bool>,
127    on_link_account: Option<OnLinkAccount>,
128    field_name: Option<String>,
129}
130
131impl AnonymousOptionsBuilder {
132    #[must_use]
133    pub fn email_domain_name(mut self, domain: impl Into<String>) -> Self {
134        self.email_domain_name = Some(domain.into());
135        self
136    }
137
138    #[must_use]
139    pub fn generate_random_email(mut self, generator: GenerateRandomEmail) -> Self {
140        self.generate_random_email = Some(generator);
141        self
142    }
143
144    #[must_use]
145    pub fn generate_name(mut self, generator: GenerateName) -> Self {
146        self.generate_name = Some(generator);
147        self
148    }
149
150    #[must_use]
151    pub fn disable_delete_anonymous_user(mut self, disabled: bool) -> Self {
152        self.disable_delete_anonymous_user = Some(disabled);
153        self
154    }
155
156    #[must_use]
157    pub fn on_link_account(mut self, callback: OnLinkAccount) -> Self {
158        self.on_link_account = Some(callback);
159        self
160    }
161
162    #[must_use]
163    pub fn field_name(mut self, field_name: impl Into<String>) -> Self {
164        self.field_name = Some(field_name.into());
165        self
166    }
167
168    #[must_use]
169    pub fn build(self) -> AnonymousOptions {
170        let defaults = AnonymousOptions::default();
171        AnonymousOptions {
172            email_domain_name: self.email_domain_name.or(defaults.email_domain_name),
173            generate_random_email: self
174                .generate_random_email
175                .or(defaults.generate_random_email),
176            generate_name: self.generate_name.or(defaults.generate_name),
177            disable_delete_anonymous_user: self
178                .disable_delete_anonymous_user
179                .unwrap_or(defaults.disable_delete_anonymous_user),
180            on_link_account: self.on_link_account.or(defaults.on_link_account),
181            field_name: self.field_name.or(defaults.field_name),
182        }
183    }
184}