Skip to main content

bitwarden_generators/
generator_client.rs

1use bitwarden_core::Client;
2
3use crate::{
4    PassphraseError, PassphraseGeneratorRequest, PasswordError, PasswordGeneratorRequest,
5    PasswordRulesError, UsernameError, UsernameGeneratorRequest, passphrase::passphrase,
6    password::password, passwordrules::parse_password_rules, username::username,
7};
8
9#[allow(missing_docs)]
10#[bitwarden_ffi::wasm_object]
11pub struct GeneratorClient {
12    client: Client,
13}
14
15#[bitwarden_ffi::wasm_export]
16impl GeneratorClient {
17    fn new(client: Client) -> Self {
18        Self { client }
19    }
20
21    /// Generates a random password.
22    ///
23    /// The character sets and password length can be customized using the `input` parameter.
24    ///
25    /// # Examples
26    ///
27    /// ```
28    /// use bitwarden_core::Client;
29    /// use bitwarden_generators::{GeneratorClientsExt, PassphraseError, PasswordGeneratorRequest};
30    ///
31    /// async fn test() -> Result<(), PassphraseError> {
32    ///     let input = PasswordGeneratorRequest {
33    ///         lowercase: true,
34    ///         uppercase: true,
35    ///         numbers: true,
36    ///         length: 20,
37    ///         ..Default::default()
38    ///     };
39    ///     let password = Client::new(None).generator().password(input).unwrap();
40    ///     println!("{}", password);
41    ///     Ok(())
42    /// }
43    /// ```
44    pub fn password(&self, input: PasswordGeneratorRequest) -> Result<String, PasswordError> {
45        password(input)
46    }
47
48    /// Parses an HTML `passwordrules` attribute string into a [`PasswordGeneratorRequest`].
49    ///
50    /// The returned request can be passed to [`GeneratorClient::password`] to produce a
51    /// password that satisfies the website's declared constraints.
52    pub fn password_rules(
53        &self,
54        rules: String,
55    ) -> Result<PasswordGeneratorRequest, PasswordRulesError> {
56        parse_password_rules(&rules)
57    }
58
59    /// Generates a random passphrase.
60    /// A passphrase is a combination of random words separated by a character.
61    /// An example of passphrase is `correct horse battery staple`.
62    ///
63    /// The number of words and their case, the word separator, and the inclusion of
64    /// a number in the passphrase can be customized using the `input` parameter.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use bitwarden_core::Client;
70    /// use bitwarden_generators::{GeneratorClientsExt, PassphraseError, PassphraseGeneratorRequest};
71    ///
72    /// async fn test() -> Result<(), PassphraseError> {
73    ///     let input = PassphraseGeneratorRequest {
74    ///         num_words: 4,
75    ///         ..Default::default()
76    ///     };
77    ///     let passphrase = Client::new(None).generator().passphrase(input).unwrap();
78    ///     println!("{}", passphrase);
79    ///     Ok(())
80    /// }
81    /// ```
82    pub fn passphrase(&self, input: PassphraseGeneratorRequest) -> Result<String, PassphraseError> {
83        passphrase(input)
84    }
85}
86
87impl GeneratorClient {
88    /// Generates a random username.
89    /// There are different username generation strategies, which can be customized using the
90    /// `input` parameter.
91    ///
92    /// Note that most generation strategies will be executed on the client side, but `Forwarded`
93    /// will use third-party services, which may require a specific setup or API key.
94    ///
95    /// ```
96    /// use bitwarden_core::Client;
97    /// use bitwarden_generators::{GeneratorClientsExt, UsernameError, UsernameGeneratorRequest};
98    ///
99    /// async fn test() -> Result<(), UsernameError> {
100    ///     let input = UsernameGeneratorRequest::Word {
101    ///         capitalize: true,
102    ///         include_number: true,
103    ///     };
104    ///     let username = Client::new(None).generator().username(input).await.unwrap();
105    ///     println!("{}", username);
106    ///     Ok(())
107    /// }
108    /// ```
109    pub async fn username(&self, input: UsernameGeneratorRequest) -> Result<String, UsernameError> {
110        username(input, self.client.internal.get_http_client()).await
111    }
112}
113
114#[allow(missing_docs)]
115pub trait GeneratorClientsExt {
116    fn generator(&self) -> GeneratorClient;
117}
118
119impl GeneratorClientsExt for Client {
120    fn generator(&self) -> GeneratorClient {
121        GeneratorClient::new(self.clone())
122    }
123}