diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..ff3d17c --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +pub mod random_string; diff --git a/src/utils/random_string.rs b/src/utils/random_string.rs new file mode 100644 index 0000000..d61cc95 --- /dev/null +++ b/src/utils/random_string.rs @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use std::sync::Arc; + +use actix_web::web; +use mockall::predicate::*; +use mockall::*; + +pub type WebGenerateRandomStringInterface = web::Data>; + +#[automock] +pub trait GenerateRandomStringInterface: Send + Sync { + fn get_random(&self, len: usize) -> String; +} + +pub struct GenerateRandomString; +impl GenerateRandomStringInterface for GenerateRandomString { + fn get_random(&self, len: usize) -> String { + use std::iter; + + use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng}; + + let mut rng: ThreadRng = thread_rng(); + + iter::repeat(()) + .map(|()| rng.sample(Alphanumeric)) + .map(char::from) + .take(len) + .collect::() + } +} + +impl GenerateRandomString { + pub fn inject() -> impl FnOnce(&mut web::ServiceConfig) { + let g = WebGenerateRandomStringInterface::new(Arc::new(GenerateRandomString)); + let f = move |cfg: &mut web::ServiceConfig| { + cfg.app_data(g); + }; + + Box::new(f) + } +} + +#[cfg(test)] +pub mod tests { + use super::*; + + use std::sync::Arc; + + pub fn mock_generate_random_string( + times: Option, + returning: String, + ) -> Arc { + let mut m = MockGenerateRandomStringInterface::new(); + + if let Some(times) = times { + m.expect_get_random() + .times(times) + .return_const(returning.to_string()); + } else { + m.expect_get_random().return_const(returning.to_string()); + } + + Arc::new(m) + } +}