crustacean_states/shards/
wa.rs

1//! For World Assembly shard requests.
2
3use crate::shards::{NSRequest, Params, BASE_URL};
4use itertools::Itertools;
5use std::{
6    fmt::{Display, Formatter},
7    string::ToString,
8};
9use strum::{AsRefStr, Display};
10use url::Url;
11
12/// One of the two World Assembly chambers (or "councils").
13#[repr(u8)]
14#[derive(Clone, Debug, Default)]
15pub enum WACouncil {
16    /// The General Assembly.
17    ///
18    /// In-game description:
19    /// "The oldest Council of the World Assembly,
20    /// the General Assembly concerns itself with international law.
21    /// Its resolutions are applied immediately upon passing in all WA member nations."
22    /// [link](https://www.nationstates.net/page=ga)
23    #[default]
24    GeneralAssembly = 1,
25    /// The Security Council.
26    ///
27    /// In-game description:
28    /// "The Security Council recognizes and responds to individual nations and regions,
29    /// with the aim of ensuring global harmony."
30    /// [link](https://www.nationstates.net/page=sc)
31    SecurityCouncil = 2,
32}
33
34/// A shard for the World Assembly.
35#[derive(AsRefStr, Clone, Debug)]
36pub enum WAShard<'a> {
37    /// Information about the WA as a whole.
38    GlobalInfo(WAGlobalShard),
39    /// Information about an individual WA chamber.
40    CouncilInfo(WACouncilShard),
41    /// Information about a resolution in a World Assembly council.
42    /// Request more information with [`ResolutionShard`]s.
43    CurrentResolution(&'a [ResolutionShard]),
44    /// Information about a previous resolution.
45    PreviousResolution(u16),
46}
47
48impl<'a> From<WAGlobalShard> for WAShard<'a> {
49    fn from(value: WAGlobalShard) -> Self {
50        Self::GlobalInfo(value)
51    }
52}
53
54impl<'a> From<WACouncilShard> for WAShard<'a> {
55    fn from(value: WACouncilShard) -> Self {
56        Self::CouncilInfo(value)
57    }
58}
59
60impl<'a> From<&'a [ResolutionShard]> for WAShard<'a> {
61    fn from(value: &'a [ResolutionShard]) -> Self {
62        WAShard::CurrentResolution(value)
63    }
64}
65
66impl<'a> From<u16> for WAShard<'a> {
67    fn from(value: u16) -> Self {
68        WAShard::PreviousResolution(value)
69    }
70}
71
72impl<'a> Display for WAShard<'a> {
73    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
74        write!(
75            f,
76            "{}",
77            match self {
78                WAShard::GlobalInfo(g) => g.to_string(),
79                WAShard::CouncilInfo(c) => c.to_string(),
80                WAShard::CurrentResolution(a) => a
81                    .iter()
82                    .fold(String::from("resolution"), |acc, s| format!("{acc}+{s:?}")),
83                WAShard::PreviousResolution(_) => String::from("resolution"),
84            }
85            .to_ascii_lowercase()
86        )
87    }
88}
89
90/// Information about the World Assembly as a whole.
91#[derive(Clone, Debug, Display)]
92pub enum WAGlobalShard {
93    /// The number of nations in the World Assembly.
94    NumNations,
95    /// The number of delegates in the World Assembly.
96    NumDelegates,
97    /// The list of delegates currently serving in the World Assembly.
98    Delegates,
99    /// The list of all World Assembly members.
100    Members,
101}
102
103/// Information for the World Assembly that is specific to a council.
104#[derive(Clone, Debug, Display)]
105pub enum WACouncilShard {
106    /// A shard that returns `[Event]`s in the World Assembly.
107    ///
108    /// [Event]: crate::parsers::happenings::Event
109    Happenings,
110    /// All the currently proposed resolutions in a World Assembly council.
111    Proposals,
112    /// The most recent resolution in a World Assembly council.
113    LastResolution,
114}
115
116/// Information about the current at-vote resolution.
117#[derive(Clone, Debug, Display)]
118pub enum ResolutionShard {
119    /// Lists every nation voting for and against the resolution.
120    Voters,
121    /// Information about how many votes each side gets over time.
122    VoteTrack,
123    /// Lists every delegate's vote, including voting power.
124    /// NOTE: this will not return the resolution text.
125    /// Votes are chronologically ordered; the oldest vote comes first.
126    DelLog,
127    /// List every delegate's vote, including voting power.
128    /// NOTE: Votes are grouped into yes and no votes.
129    DelVotes,
130}
131
132/// Request information about the WA.
133#[derive(Clone, Debug)]
134pub enum WARequest<'a> {
135    /// Information about the WA as a whole.
136    Global(GlobalRequest<'a>),
137    /// Information about a WA council.
138    Council(CouncilRequest<'a>),
139    /// Information about the at-vote resolution.
140    AtVoteResolution(ResolutionRequest<'a>),
141    /// Information about a previous resolution.
142    PastResolution(ResolutionArchiveRequest),
143}
144
145/// Request information about the WA as a whole.
146#[derive(Clone, Debug)]
147pub struct GlobalRequest<'a> {
148    shards: &'a [WAGlobalShard],
149}
150
151impl<'a> GlobalRequest<'a> {
152    /// Create a new request about the WA as a whole.
153    pub fn new(shards: &'a [WAGlobalShard]) -> Self {
154        Self { shards }
155    }
156}
157
158/// Request information about a WA council.
159#[derive(Clone, Debug)]
160pub struct CouncilRequest<'a> {
161    council: WACouncil,
162    shards: &'a [WAShard<'a>],
163}
164
165impl<'a> CouncilRequest<'a> {
166    /// Create a request about a WA council.
167    pub fn new(council: WACouncil, shards: &'a [WAShard<'a>]) -> Self {
168        Self { council, shards }
169    }
170}
171
172/// Request information about the current at-vote resolution.
173#[derive(Clone, Debug)]
174pub struct ResolutionRequest<'a> {
175    council: WACouncil,
176    shards: &'a [ResolutionShard],
177}
178
179impl<'a> ResolutionRequest<'a> {
180    /// Create a request about the current at-vote resolution.
181    pub fn new(council: WACouncil, shards: &'a [ResolutionShard]) -> Self {
182        Self { council, shards }
183    }
184}
185
186/// Request information about previous resolutions.
187#[derive(Clone, Debug)]
188pub struct ResolutionArchiveRequest {
189    council: WACouncil,
190    id: u16,
191}
192
193impl ResolutionArchiveRequest {
194    /// Create a request about previous resolutions.
195    pub fn new(council: WACouncil, id: u16) -> Self {
196        Self { council, id }
197    }
198}
199
200impl<'a> NSRequest for WARequest<'a> {
201    fn as_url(&self) -> Url {
202        Url::parse_with_params(
203            BASE_URL,
204            Params::default()
205                .insert(
206                    "wa",
207                    match self {
208                        WARequest::Global(_) => None,
209                        WARequest::Council(CouncilRequest { council, .. }) => Some(council.clone()),
210                        WARequest::AtVoteResolution(ResolutionRequest { council, .. }) => {
211                            Some(council.clone())
212                        }
213                        WARequest::PastResolution(ResolutionArchiveRequest { council, .. }) => {
214                            Some(council.clone())
215                        }
216                    }
217                    .unwrap_or_default() as u8,
218                )
219                .insert_on(
220                    "id",
221                    &if let WARequest::PastResolution(ResolutionArchiveRequest { id, .. }) = self {
222                        Some(id)
223                    } else {
224                        None
225                    },
226                )
227                .insert(
228                    "q",
229                    match self {
230                        WARequest::Global(GlobalRequest { shards }) => shards.iter().join("+"),
231                        WARequest::Council(CouncilRequest { shards, .. }) => {
232                            shards.iter().join("+")
233                        }
234                        WARequest::AtVoteResolution(ResolutionRequest { shards, .. }) => {
235                            format!("resolution+{}", shards.iter().join("+"))
236                        }
237                        WARequest::PastResolution(_) => String::from("resolution"),
238                    }
239                    .to_ascii_lowercase(),
240                ),
241        )
242        .unwrap()
243    }
244}