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
120
121
122
123
124
125
126
127
use std::sync::Arc;

/// A smart constructor validating a deflate compression level
#[derive(Clone, Debug)]
pub struct NSQDeflateLevel {
    pub(crate) level: u8
}

impl NSQDeflateLevel {
    /// Compression level N must be > 0 && < 10
    pub fn new(level: u8) -> Option<NSQDeflateLevel> {
        if level < 1 || level > 9 {
            None
        } else {
            Some(NSQDeflateLevel { level })
        }
    }
    /// Return the compression level
    pub fn get(&self) -> u8 {
        self.level
    }
}

/// NSQD TLS encryption options
#[derive(Clone)]
pub struct NSQConfigSharedTLS {
    pub(crate) required:      bool,
    pub(crate) client_config: Option<Arc<rustls::ClientConfig>>,
    pub(crate) domain_name:   String,
}

impl NSQConfigSharedTLS {
    /// Construct a TLS configuration object. Defaults are insecure.
    pub fn new<S: Into<String>>(domain: S) -> Self {
        NSQConfigSharedTLS {
            required:      true,
            client_config: None,
            domain_name:   domain.into(),
        }
    }
    /// If the connection should fail if TLS is not supported. Defaults to true.
    pub fn set_required(mut self, required: bool) -> Self {
        self.required = required;

        self
    }
    /// Set TLS configuration object from `rustls` crate.
    pub fn set_client_config(mut self, client_config: Arc<rustls::ClientConfig>) -> Self {
        self.client_config = Some(client_config);

        self
    }
}

/// NSQD TCP compression options
#[derive(Debug, Clone)]
pub enum NSQConfigSharedCompression {
    Deflate(NSQDeflateLevel)
}

/// Configuration options shared by both produces and consumers
#[derive(Clone)]
pub struct NSQConfigShared {
    pub(crate) backoff_max_wait:      std::time::Duration,
    pub(crate) backoff_healthy_after: std::time::Duration,
    pub(crate) compression:           Option<NSQConfigSharedCompression>,
    pub(crate) tls:                   Option<NSQConfigSharedTLS>,
    pub(crate) credentials:           Option<Vec<u8>>,
    pub(crate) client_id:             Option<String>,
}

impl NSQConfigShared {
    /// Construct a configuration with sane defaults.
    pub fn new() -> Self {
        NSQConfigShared {
            backoff_max_wait:      std::time::Duration::new(60, 0),
            backoff_healthy_after: std::time::Duration::new(45, 0),
            compression:           None,
            tls:                   None,
            credentials:           None,
            client_id:             None,
        }
    }

    /// The maximum reconnect backoff wait. Defaults to 60 seconds.
    pub fn set_backoff_max_wait(mut self, duration: std::time::Duration) -> Self {
        self.backoff_max_wait = duration;

        self
    }
    /// How long a connection should be healthy before backoff is reset. Defaults to 45 seconds.
    pub fn set_backoff_healthy_after(mut self, duration: std::time::Duration) -> Self {
        self.backoff_healthy_after = duration;

        self
    }
    /// Connection compression options. Defaults to no compression.
    pub fn set_compression(mut self, compression: NSQConfigSharedCompression) -> Self {
        self.compression = Some(compression);

        self
    }
    /// Credentials to send NSQD if authentication is requried. Defaults to no credentials.
    pub fn set_credentials(mut self, credentials: Vec<u8>) -> Self {
        self.credentials = Some(credentials);

        self
    }
    /// Connection encryption options. Defaults to no encryption
    pub fn set_tls(mut self, tls: NSQConfigSharedTLS) -> Self {
        self.tls = Some(tls);

        self
    }
    /// A string used to identify an NSQ client. Defaults to anonymous identity.
    pub fn set_client_id<S: Into<String>>(mut self, client_id: S) -> Self {
        self.client_id = Some(client_id.into());

        self
    }
}

impl Default for NSQConfigShared {
    fn default() -> Self {
        Self::new()
    }
}