Skip to main content

ipwhois/
options.rs

1//! Per-call options for [`crate::IpWhois::lookup_with`] and
2//! [`crate::IpWhois::bulk_lookup_with`], and the same shape used to set
3//! defaults on the client.
4//!
5//! Four fields, exposed as a typed builder: `lang`, `fields`, `security`,
6//! `rate`.
7
8/// Options accepted by lookup calls and by the client as defaults.
9///
10/// Every field is optional. Per-call options always override the defaults
11/// stored on the client.
12///
13/// # Example
14///
15/// ```
16/// use ipwhois::Options;
17///
18/// let opts = Options::new()
19///     .with_lang("en")
20///     .with_fields(["success", "country", "city", "flag.emoji"])
21///     .with_security(true)
22///     .with_rate(true);
23/// ```
24#[derive(Debug, Default, Clone, PartialEq, Eq)]
25pub struct Options {
26    pub(crate) lang: Option<String>,
27    pub(crate) fields: Option<Vec<String>>,
28    pub(crate) security: Option<bool>,
29    pub(crate) rate: Option<bool>,
30}
31
32impl Options {
33    /// Create an empty options set with no overrides.
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    /// Set the response language.
39    ///
40    /// Must be one of [`crate::SUPPORTED_LANGUAGES`]. Validated when the
41    /// call is made — invalid values surface as
42    /// [`crate::Error::InvalidArgument`], no request is sent.
43    pub fn with_lang(mut self, lang: impl Into<String>) -> Self {
44        self.lang = Some(lang.into());
45        self
46    }
47
48    /// Restrict the response to a specific set of fields.
49    ///
50    /// Include `"success"` if you rely on the success flag for error
51    /// checking — when `fields` is set, the API only returns the fields
52    /// you ask for.
53    pub fn with_fields<I, S>(mut self, fields: I) -> Self
54    where
55        I: IntoIterator<Item = S>,
56        S: Into<String>,
57    {
58        self.fields = Some(fields.into_iter().map(Into::into).collect());
59        self
60    }
61
62    /// Toggle the threat-detection (`security`) block in responses.
63    /// Requires the Business plan or above.
64    pub fn with_security(mut self, enabled: bool) -> Self {
65        self.security = Some(enabled);
66        self
67    }
68
69    /// Toggle the `rate` block in responses (`limit`, `remaining`).
70    /// Requires the Basic plan or above.
71    pub fn with_rate(mut self, enabled: bool) -> Self {
72        self.rate = Some(enabled);
73        self
74    }
75
76    /// Merge `other` on top of `self` — every field set on `other` wins,
77    /// otherwise `self`'s value is kept.
78    pub(crate) fn merged_with(&self, other: &Options) -> Options {
79        Options {
80            lang: other.lang.clone().or_else(|| self.lang.clone()),
81            fields: other.fields.clone().or_else(|| self.fields.clone()),
82            security: other.security.or(self.security),
83            rate: other.rate.or(self.rate),
84        }
85    }
86}