Skip to main content

esi_openapi/groups/
mod.rs

1//! Endpoint groups
2
3mod access_list;
4pub use access_list::*;
5mod activities;
6pub use activities::*;
7mod alliance;
8pub use alliance::*;
9mod assets;
10pub use assets::*;
11mod bookmarks;
12pub use bookmarks::*;
13mod calendar;
14pub use calendar::*;
15mod character;
16pub use character::*;
17mod clones;
18pub use clones::*;
19mod contacts;
20pub use contacts::*;
21mod contracts;
22pub use contracts::*;
23mod corporation;
24pub use corporation::*;
25mod corporation_projects;
26pub use corporation_projects::*;
27mod cosmetics;
28pub use cosmetics::*;
29mod dogma;
30pub use dogma::*;
31mod faction_warfare;
32pub use faction_warfare::*;
33mod fittings;
34pub use fittings::*;
35mod freelance_jobs;
36pub use freelance_jobs::*;
37mod fleets;
38pub use fleets::*;
39mod incursions;
40pub use incursions::*;
41mod industry;
42pub use industry::*;
43mod insurance;
44pub use insurance::*;
45mod killmails;
46pub use killmails::*;
47mod location;
48pub use location::*;
49mod loyalty;
50pub use loyalty::*;
51mod mail;
52pub use mail::*;
53mod market;
54pub use market::*;
55mod military_campaigns;
56pub use military_campaigns::*;
57mod opportunities;
58pub use opportunities::*;
59mod paragon_hub;
60pub use paragon_hub::*;
61mod planetary_interaction;
62pub use planetary_interaction::*;
63mod routes;
64pub use routes::*;
65mod meta;
66pub use meta::*;
67mod search;
68pub use search::*;
69mod skills;
70pub use skills::*;
71mod sovereignty;
72pub use sovereignty::*;
73mod structures;
74pub use structures::*;
75mod status;
76pub use status::*;
77mod universe;
78pub use universe::*;
79mod user_interface;
80pub use user_interface::*;
81mod wallet;
82pub use wallet::*;
83mod wars;
84pub use wars::*;
85
86/// Cursor for walking through paginated listings.
87///
88/// Pass `after` or `before` from a page as the matching parameter of the next request.
89#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
90pub struct Cursor {
91    /// Cursor to continue walking forwards in time.
92    pub after: Option<String>,
93    /// Cursor to continue walking backwards in time.
94    pub before: Option<String>,
95}
96
97/// One page of a cursor-paginated listing, with the cursors to continue walking it.
98///
99/// ESI names the array of records after what the endpoint lists (`projects`,
100/// `listings`, `objectives`, ...); here it is always [`Page::items`]. A response
101/// without the array reads as a page without records.
102#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
103pub struct Page<T> {
104    /// Cursors to continue walking the list.
105    pub cursor: Option<Cursor>,
106    /// The records in the page.
107    #[serde(
108        default = "Vec::new",
109        alias = "projects",
110        alias = "contributors",
111        alias = "freelance_jobs",
112        alias = "participants",
113        alias = "objectives",
114        alias = "listings"
115    )]
116    pub items: Vec<T>,
117}
118
119#[cfg(test)]
120mod page_tests {
121    use super::Page;
122
123    #[test]
124    fn test_page_reads_every_key_esi_uses() {
125        for key in [
126            "projects",
127            "contributors",
128            "freelance_jobs",
129            "participants",
130            "objectives",
131            "listings",
132        ] {
133            let json =
134                format!(r#"{{"cursor": {{"after": "a", "before": null}}, "{key}": [1, 2]}}"#);
135            let page: Page<i64> = serde_json::from_str(&json).unwrap();
136            assert_eq!(page.items, [1, 2], "{key}");
137            assert_eq!(page.cursor.unwrap().after.as_deref(), Some("a"));
138        }
139    }
140
141    #[test]
142    fn test_page_without_records_or_cursor_is_empty() {
143        let page: Page<i64> = serde_json::from_str("{}").unwrap();
144        assert!(page.items.is_empty() && page.cursor.is_none());
145        let page: Page<i64> =
146            serde_json::from_str(r#"{"cursor": {"after": null, "before": null}}"#).unwrap();
147        assert!(page.items.is_empty());
148    }
149
150    #[test]
151    fn test_page_round_trips() {
152        let page = Page {
153            cursor: None,
154            items: vec![1_i64, 2],
155        };
156        let json = serde_json::to_string(&page).unwrap();
157        assert_eq!(serde_json::from_str::<Page<i64>>(&json).unwrap(), page);
158    }
159}