gw2lib_model/maps/
continents.rs

1mod floors;
2
3use std::collections::BTreeSet;
4
5use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
6use serde_tuple::{Deserialize_tuple, Serialize_tuple};
7
8pub use crate::maps::continents::floors::*;
9use crate::{BulkEndpoint, Endpoint, EndpointWithId};
10
11pub type ContinentId = u32;
12
13#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Serialize_tuple, Deserialize_tuple)]
14#[cfg_attr(test, serde(deny_unknown_fields))]
15pub struct Dimensions {
16    pub width: u32,
17    pub height: u32,
18}
19
20#[derive(Clone, Debug, Serialize)]
21#[cfg_attr(test, serde(deny_unknown_fields))]
22pub struct Continent {
23    /// The id of the continent.
24    pub id: ContinentId,
25    /// The name of the continent.
26    pub name: String,
27    /// The dimensions of the continent.
28    pub continent_dims: Dimensions,
29    /// The minimal zoom level for use with the map tile service.
30    pub min_zoom: u8,
31    /// The maximum zoom level for use with the map tile service.
32    pub max_zoom: u8,
33    /// A list of floors ids available for this continent.
34    #[serde(serialize_with = "serialize_floor")]
35    pub floors: BTreeSet<ContinentFloorId>,
36}
37
38fn serialize_floor<S>(floors: &BTreeSet<ContinentFloorId>, s: S) -> Result<S::Ok, S::Error>
39where
40    S: Serializer,
41{
42    let mut seq = s.serialize_seq(Some(floors.len()))?;
43    for id in floors {
44        seq.serialize_element(&id.floor)?;
45    }
46    seq.end()
47}
48
49impl<'de> Deserialize<'de> for Continent {
50    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51    where
52        D: Deserializer<'de>,
53    {
54        #[derive(Deserialize)]
55        struct Intermediate {
56            id: ContinentId,
57            name: String,
58            continent_dims: Dimensions,
59            min_zoom: u8,
60            max_zoom: u8,
61            floors: BTreeSet<FloorId>,
62        }
63
64        let intermediate: Intermediate = Deserialize::deserialize(deserializer)?;
65        let floors = intermediate
66            .floors
67            .iter()
68            .map(|id| ContinentFloorId {
69                continent: intermediate.id,
70                floor: *id,
71            })
72            .collect();
73
74        Ok(Continent {
75            id: intermediate.id,
76            name: intermediate.name,
77            continent_dims: intermediate.continent_dims,
78            min_zoom: intermediate.min_zoom,
79            max_zoom: intermediate.max_zoom,
80            floors,
81        })
82    }
83}
84
85impl EndpointWithId for Continent {
86    type IdType = ContinentId;
87}
88impl Endpoint for Continent {
89    const AUTHENTICATED: bool = false;
90    const LOCALE: bool = true;
91    const URL: &'static str = "v2/continents";
92    const VERSION: &'static str = "2023-03-31T00:00:00.000Z";
93}
94
95impl BulkEndpoint for Continent {
96    const ALL: bool = true;
97
98    fn id(&self) -> &Self::IdType {
99        &self.id
100    }
101}