modio/request/mods/metadata/
delete_mod_metadata.rs1use std::collections::BTreeMap;
2use std::future::IntoFuture;
3
4use crate::client::Client;
5use crate::request::{ArrayParams, Output, RequestBuilder, Route};
6use crate::response::{NoContent, ResponseFuture};
7use crate::types::id::{GameId, ModId};
8use crate::types::mods::MetadataMap;
9
10pub struct DeleteModMetadata<'a> {
12 http: &'a Client,
13 game_id: GameId,
14 mod_id: ModId,
15 fields: DeleteModMetadataFields,
16}
17
18struct DeleteModMetadataFields {
19 metadata: MetadataMap,
20}
21
22impl DeleteModMetadataFields {
23 fn flatten(&self) -> Vec<String> {
24 let sorted = self.metadata.iter().collect::<BTreeMap<_, _>>();
25 let mut metadata = Vec::new();
26 for (key, values) in sorted {
27 if values.is_empty() {
28 metadata.push(key.to_owned());
29 continue;
30 }
31 for value in values {
32 let mut v = key.clone();
33 v.push(':');
34 v.push_str(value);
35 metadata.push(v);
36 }
37 }
38 metadata
39 }
40}
41
42impl<'a> DeleteModMetadata<'a> {
43 pub(crate) const fn new(
44 http: &'a Client,
45 game_id: GameId,
46 mod_id: ModId,
47 metadata: MetadataMap,
48 ) -> Self {
49 Self {
50 http,
51 game_id,
52 mod_id,
53 fields: DeleteModMetadataFields { metadata },
54 }
55 }
56}
57
58impl IntoFuture for DeleteModMetadata<'_> {
59 type Output = Output<NoContent>;
60 type IntoFuture = ResponseFuture<NoContent>;
61
62 fn into_future(self) -> Self::IntoFuture {
63 let route = Route::DeleteModMetadata {
64 game_id: self.game_id,
65 mod_id: self.mod_id,
66 };
67 let metadata = self.fields.flatten();
68 let form = ArrayParams::new("metadata[]", &metadata);
69 match RequestBuilder::from_route(&route).form(&form) {
70 Ok(req) => self.http.request(req),
71 Err(err) => ResponseFuture::failed(err),
72 }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use serde_test::{assert_ser_tokens, Token};
79
80 use super::{ArrayParams, DeleteModMetadataFields, MetadataMap};
81
82 #[test]
83 pub fn serialize_fields() {
84 let mut metadata = MetadataMap::new();
85 metadata.insert(
86 String::from("aaa"),
87 vec![String::from("bbb"), String::from("ccc")],
88 );
89 metadata.insert(String::from("ddd"), vec![]);
90 metadata.insert(
91 String::from("eee"),
92 vec![String::from("fff"), String::from("ggg")],
93 );
94 let fields = DeleteModMetadataFields { metadata };
95 let flatten = fields.flatten();
96 let params = ArrayParams::new("metadata[]", &flatten);
97
98 assert_ser_tokens(
99 ¶ms,
100 &[
101 Token::Map { len: Some(5) },
102 Token::Str("metadata[]"),
103 Token::Str("aaa:bbb"),
104 Token::Str("metadata[]"),
105 Token::Str("aaa:ccc"),
106 Token::Str("metadata[]"),
107 Token::Str("ddd"),
108 Token::Str("metadata[]"),
109 Token::Str("eee:fff"),
110 Token::Str("metadata[]"),
111 Token::Str("eee:ggg"),
112 Token::MapEnd,
113 ],
114 );
115
116 let qs = serde_urlencoded::to_string(¶ms).unwrap();
117 assert_eq!(
118 "metadata%5B%5D=aaa%3Abbb&metadata%5B%5D=aaa%3Accc&metadata%5B%5D=ddd&metadata%5B%5D=eee%3Afff&metadata%5B%5D=eee%3Aggg",
119 qs
120 );
121 }
122}