Skip to main content

banished_nexus/
lib.rs

1#![doc = include_str!("../README.md")]
2#![doc(
3    html_logo_url = "https://tanepiper.github.io/unbanished/assets/un-banished-icon.svg",
4    html_favicon_url = "https://tanepiper.github.io/unbanished/favicon.svg"
5)]
6
7pub mod api;
8pub mod install;
9pub mod nxm;
10
11#[cfg(feature = "native")]
12pub mod native;
13
14/// The game's domain name on Nexus Mods, used in its addresses.
15pub const GAME_DOMAIN: &str = "banished";
16
17/// The game's id on Nexus Mods, used by the GraphQL API.
18pub const GAME_ID: u32 = 617;
19
20/// The REST API (version 1), which needs an API key.
21pub const API_V1: &str = "https://api.nexusmods.com/v1";
22
23/// The GraphQL API (version 2), which answers searches without a key.
24pub const API_V2: &str = "https://api.nexusmods.com/v2/graphql";
25
26/// The application that sends the requests, as Nexus Mods asks every application to say.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct App {
29    /// The application's name, the same in every version: `Un-Banished`.
30    pub name: String,
31    /// The application's version, for example `0.2.0`.
32    pub version: String,
33}
34
35impl App {
36    /// Un-Banished at the given engine version.
37    pub fn un_banished(version: &str) -> App {
38        App {
39            name: "Un-Banished".to_string(),
40            version: version.to_string(),
41        }
42    }
43}
44
45/// An HTTP request to send.
46#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct Request {
48    /// `GET` or `POST`.
49    pub method: &'static str,
50    /// The full address.
51    pub url: String,
52    /// The headers, as name and value.
53    pub headers: Vec<(String, String)>,
54    /// The body (JSON for GraphQL), if any.
55    pub body: Option<String>,
56}
57
58/// Something that went wrong with Nexus Mods.
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub enum Error {
61    /// The request needs an API key and none is set.
62    NoKey,
63    /// The request could not be sent or the answer could not be read (the message says why).
64    Network(String),
65    /// Nexus Mods answered with an error: the HTTP status and its message.
66    Status(u16, String),
67    /// The answer was not what was expected.
68    Answer(String),
69    /// Downloads of this file need Premium, or a link from the website's "Mod Manager
70    /// Download" button.
71    NeedsPremium,
72    /// The archive is in a format that cannot be opened here (its extension).
73    Unsupported(String),
74    /// The download holds no `.pkm` package.
75    NoPackage,
76}
77
78impl std::fmt::Display for Error {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        match self {
81            Error::NoKey => write!(f, "no Nexus Mods API key is set"),
82            Error::Network(m) => write!(f, "could not reach Nexus Mods: {m}"),
83            Error::Status(s, m) => write!(f, "Nexus Mods answered {s}: {m}"),
84            Error::Answer(m) => write!(f, "unexpected answer from Nexus Mods: {m}"),
85            Error::NeedsPremium => write!(
86                f,
87                "this download needs Nexus Mods Premium, or a link from the mod page's \
88                 \"Mod Manager Download\" button"
89            ),
90            Error::Unsupported(e) => write!(
91                f,
92                "a .{e} archive cannot be opened here; download it from Nexus Mods and put its \
93                 .pkm file in the WinData folder"
94            ),
95            Error::NoPackage => write!(f, "the download holds no .pkm mod package"),
96        }
97    }
98}
99
100impl std::error::Error for Error {}