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
use futures_util::TryStreamExt;
use serde::Deserialize;
use crate::prelude::*;
pub use crate::types::mods::MetadataMap;
pub struct Metadata {
modio: Modio,
game: u32,
mod_id: u32,
}
impl Metadata {
pub(crate) fn new(modio: Modio, game: u32, mod_id: u32) -> Self {
Self {
modio,
game,
mod_id,
}
}
pub async fn get(self) -> Result<MetadataMap> {
#[derive(Deserialize)]
struct KV {
metakey: String,
metavalue: String,
}
let route = Route::GetModMetadata {
game_id: self.game,
mod_id: self.mod_id,
};
let filter = Default::default();
let mut it = Query::<KV>::new(self.modio, route, filter).iter().await?;
let (size, _) = it.size_hint();
let mut map = MetadataMap::with_capacity(size);
while let Some(kv) = it.try_next().await? {
map.entry(kv.metakey).or_default().push(kv.metavalue);
}
Ok(map)
}
#[allow(clippy::should_implement_trait)]
pub async fn add(self, metadata: MetadataMap) -> Result<()> {
let route = Route::AddModMetadata {
game_id: self.game,
mod_id: self.mod_id,
};
self.modio
.request(route)
.form(&metadata)
.send::<Message>()
.await?;
Ok(())
}
pub async fn delete(self, metadata: MetadataMap) -> Result<Deletion> {
let route = Route::DeleteModMetadata {
game_id: self.game,
mod_id: self.mod_id,
};
self.modio.request(route).form(&metadata).send().await
}
}
#[doc(hidden)]
impl serde::ser::Serialize for MetadataMap {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeMap;
let len = self.values().map(|v| std::cmp::max(1, v.len())).sum();
let mut map = serializer.serialize_map(Some(len))?;
for (k, vals) in self.iter() {
if vals.is_empty() {
map.serialize_entry("metadata[]", k)?;
}
for v in vals {
map.serialize_entry("metadata[]", &format!("{}:{}", k, v))?;
}
}
map.end()
}
}