mtgapi_client/api/set/
filter.rs

1use crate::api::set::filtertypes::SetBlock;
2use itertools::Itertools;
3use std::fmt::Display;
4
5const SEP_OR: &str = "|";
6
7/// Builder for filtered set requests
8#[derive(Clone, Debug)]
9pub struct SetFilterBuilder {
10    filter: String,
11}
12
13impl SetFilterBuilder {
14    fn new() -> SetFilterBuilder {
15        SetFilterBuilder {
16            filter: String::new(),
17        }
18    }
19
20    /// Creates a Setilter with the specified filter parameters
21    ///
22    /// ```
23    /// # use mtgapi_client::prelude::*;
24    /// let builder = SetFilter::builder();
25    /// let filter = builder
26    ///     .name("Khans of Tarkir")
27    ///     .block(SetBlock::KhansOfTarkir)
28    ///     .build();
29    /// assert!(filter == SetFilter("name=Khans of Tarkir&block=Khans of Tarkir".to_string()))
30    /// ```
31    #[allow(dead_code)]
32    pub fn build(self) -> SetFilter {
33        SetFilter(self.filter)
34    }
35
36    /// Create a custom filter
37    ///
38    /// ```
39    /// # use mtgapi_client::prelude::*;
40    /// let builder = SetFilter::builder();
41    /// let filter = builder.custom("name", "Dominaria")
42    ///     .build();
43    /// assert!(filter == SetFilter("name=Dominaria".to_string()))
44    /// ```
45    #[allow(dead_code)]
46    pub fn custom<'a, T>(mut self, key: T, value: T) -> SetFilterBuilder
47    where
48        T: Into<&'a str>,
49    {
50        self.add_filter(key.into(), value.into());
51        self
52    }
53
54    /// Every set that (partially) matches the specified name will match the filter
55    ///
56    /// ```
57    /// # use mtgapi_client::prelude::*;
58    /// let builder = SetFilter::builder();
59    /// let filter = builder.name("Dominaria")
60    ///     .build();
61    /// assert!(filter == SetFilter("name=Dominaria".to_string()))
62    /// ```
63    #[allow(dead_code)]
64    pub fn name<'a, T>(mut self, name: T) -> SetFilterBuilder
65    where
66        T: Into<&'a str>,
67    {
68        self.add_filter("name", name.into());
69        self
70    }
71
72    /// Every set that (partially) matches one of the specified names will match the filter
73    ///
74    /// ```
75    /// # use mtgapi_client::prelude::*;
76    /// let builder = SetFilter::builder();
77    /// let filter = builder.names(&vec!["Dominaria", "Core Set 2019"])
78    ///     .build();
79    /// assert!(filter == SetFilter("name=Dominaria|Core Set 2019".to_string()));
80    /// ```
81    #[allow(dead_code)]
82    pub fn names<T>(mut self, names: &[T]) -> SetFilterBuilder
83    where
84        T: Display,
85    {
86        let values = names.iter().join(SEP_OR);
87        self.add_filter("name", &values);
88        self
89    }
90
91    /// Every set that (partially) matches the specified block will match the filter
92    ///
93    /// ```
94    /// # use mtgapi_client::prelude::*;
95    /// let builder = SetFilter::builder();
96    /// let filter = builder.block(SetBlock::Amonkhet)
97    ///     .build();
98    /// assert!(filter == SetFilter("block=Amonkhet".to_string()))
99    /// ```
100    #[allow(dead_code)]
101    pub fn block(mut self, block: SetBlock) -> SetFilterBuilder {
102        self.add_filter("block", &block.as_str());
103        self
104    }
105
106    /// Every set that (partially) matches one of the specified blocks will match the filter
107    ///
108    /// ```
109    /// # use mtgapi_client::prelude::*;
110    /// let builder = SetFilter::builder();
111    /// let filter = builder.blocks(&vec![SetBlock::Amonkhet, SetBlock::Ixalan])
112    ///     .build();
113    /// assert!(filter == SetFilter("block=Amonkhet|Ixalan".to_string()));
114    /// ```
115    #[allow(dead_code)]
116    pub fn blocks(mut self, blocks: &[SetBlock]) -> SetFilterBuilder {
117        let values = blocks.iter().map(|value| value.as_str()).join(SEP_OR);
118        self.add_filter("block", &values);
119        self
120    }
121
122    fn add_filter<T>(&mut self, key: T, values: T)
123    where
124        T: Display,
125    {
126        if !self.filter.is_empty() {
127            self.filter = [&self.filter, "&"].join("");
128        }
129        self.filter = self.filter.clone() + &[key, values].iter().join("=")
130    }
131}
132
133/// Wrapper around the filter string to be used for filtered set api requests
134#[derive(PartialEq, Eq, Clone, Debug)]
135pub struct SetFilter(pub String);
136
137impl SetFilter {
138    /// Creates a new SetFilterBuilder
139    #[allow(dead_code)]
140    pub fn builder() -> SetFilterBuilder {
141        SetFilterBuilder::new()
142    }
143}