1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::sdk::authentication::Authenticate;

use super::error::SDKError;

/// A builder for the options
///
/// Example:
/// ```ignore
/// let authentication = SecretKeyCredential::new("test".to_string(), "test".to_string());
///
/// OptionsBuilder::new()
///     .with_license("test_license")
///     .with_logging()
///     .authenticate(authentication)
///     .build()
///     .expect("Authentication failed")
/// ```
pub struct OptionsBuilder {
    license: String,
    num_retries: u64,
    logging_enabled: bool,
    headers: Vec<(String, String)>,
    authentication: Option<Box<dyn Authenticate>>,
}

// Allowing this because it is a builder pattern
#[allow(clippy::new_without_default)]
impl OptionsBuilder {
    pub fn new() -> Self {
        Self {
            license: "".to_string(),
            num_retries: 10,
            logging_enabled: false,
            headers: vec![],
            authentication: None,
        }
    }

    /// Builds the builder into options with the parameters you set
    /// Returns an error if authentication is not set
    pub fn build(self) -> Result<Options, SDKError> {
        if let Some(auth) = self.authentication {
            return Ok(Options {
                license: self.license,
                num_retries: self.num_retries,
                logging_enabled: self.logging_enabled,
                headers: self.headers,
                authentication: auth,
            });
        }
        Err(SDKError {
            code: None,
            detail: Some("Authentication Required".to_string()),
        })
    }

    /// Adds a license string to the options
    pub fn with_license(mut self, license: &str) -> Self {
        self.license = license.to_string();
        self
    }

    /// Forces a maximum number of retries that a request will attempt to handle.
    pub fn with_retries(mut self, num_retries: u64) -> Self {
        self.num_retries = num_retries;
        self
    }

    /// Enables Logging
    pub fn with_logging(mut self) -> Self {
        self.logging_enabled = true;
        self
    }

    /// Adds a set of custom headers to your request.
    pub fn with_headers(mut self, headers: Vec<(String, String)>) -> Self {
        self.headers = headers;
        self
    }

    /// Inserts the authentication into the options.
    pub fn authenticate(mut self, authentication: Box<dyn Authenticate>) -> Self {
        self.authentication = Some(authentication);
        self
    }
}

/// Options that can be passed into a new client
/// <num_retries>: the number of retries that the client with run before giving up.
/// <logging_enabled>: whether we should send logging data
/// <headers>: Custom headers that you can pass in
/// <authentication>: A authentication for Smarty
pub struct Options {
    pub(crate) license: String,

    // Retry Sender
    pub(crate) num_retries: u64,

    // Logger
    pub(crate) logging_enabled: bool,

    // Custom Headers
    pub(crate) headers: Vec<(String, String)>,

    // Authentication
    pub(crate) authentication: Box<dyn Authenticate>,
}

impl Clone for Options {
    fn clone(&self) -> Self {
        Self {
            license: self.license.clone(),
            num_retries: self.num_retries,
            logging_enabled: self.logging_enabled,
            headers: self.headers.clone(),
            authentication: self.authentication.clone_box(),
        }
    }
}