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}