edsm_dumps_model/model/
station.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use strum::EnumIter;
4use variant_count::VariantCount;
5
6use super::bgs;
7use super::dec::{date_format, date_format_opt};
8use super::RootEntry;
9
10use super::util::DisplayViaSerde;
11use crate::display_via_serde;
12
13use serde;
14
15// Main Type
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
19#[serde(rename_all = "camelCase")]
20#[serde(deny_unknown_fields)]
21pub struct Station {
22    pub id: u64,
23    // Attributes
24    pub allegiance: Option<bgs::Allegiance>,
25    pub body: Option<StationBody>,
26    pub commodities: Option<Vec<Commodity>>,
27    pub controlling_faction: Option<bgs::ControllingFaction>,
28    pub distance_to_arrival: Option<f32>,
29    pub economy: Option<bgs::Economy>,
30    pub government: Option<bgs::Government>,
31    pub have_market: bool,
32    pub have_outfitting: bool,
33    pub have_shipyard: bool,
34    pub market_id: Option<u64>,
35    pub name: String,
36    pub other_services: Vec<OtherService>,
37    pub outfitting: Option<Vec<Outfitting>>,
38    pub second_economy: Option<bgs::Economy>,
39    pub ships: Option<Vec<Ship>>,
40    pub system_id: Option<u64>,
41    pub system_id64: Option<u64>,
42    pub system_name: Option<String>,
43    #[serde(rename = "type")]
44    pub typ: Option<StationType>,
45    // Metadata
46    pub update_time: UpdateTime,
47}
48
49impl RootEntry for Station {
50    fn entry_id(&self) -> u64 {
51        self.id
52    }
53
54    fn type_name() -> &'static str {
55        "station"
56    }
57
58    fn time(&self) -> DateTime<Utc> {
59        self.update_time.information
60    }
61}
62
63// Filed Type
64
65#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
66#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
67#[serde(rename_all = "camelCase")]
68#[serde(deny_unknown_fields)]
69pub struct Commodity {
70    id: Option<String>,
71    name: String,
72    // Attributes
73    buy_price: u64,
74    demand: u64,
75    sell_price: u64,
76    stock: u64,
77    stock_bracket: u64,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, EnumIter, VariantCount)]
81#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
82#[serde(deny_unknown_fields)]
83pub enum OtherService {
84    #[serde(rename = "Black Market")]
85    BlackMarket,
86    Contacts,
87    #[serde(rename = "Crew Lounge")]
88    CrewLounge,
89    #[serde(rename = "Interstellar Factors Contact")]
90    InterstellarFactorsContact,
91    #[serde(rename = "Material Trader")]
92    MaterialTrader,
93    Missions,
94    Refuel,
95    Repair,
96    Restock,
97    #[serde(rename = "Search and Rescue")]
98    SearchAndRescue,
99    #[serde(rename = "Technology Broker")]
100    TechnologyBroker,
101    Tuning,
102    #[serde(rename = "Universal Cartographics")]
103    UniversalCartographics,
104    #[serde(rename = "Apex Interstellar Transport")]
105    ApexInterstellarTransport,
106    #[serde(rename = "Frontline Solutions")]
107    FrontlineSolutions,
108    #[serde(rename = "Pioneer Supplies")]
109    PioneerSupplies,
110    #[serde(rename = "Vista Genomics")]
111    VistaGenomics,
112    #[serde(rename = "System colonisation")]
113    SystemColonisation,
114    #[serde(rename = "Fleet carrier administration")]
115    FleetCarrierAdministration,
116    #[serde(rename = "Fleet carrier vendor")]
117    FleetCarrierVendor,
118    Bartender,
119}
120
121display_via_serde!(OtherService);
122
123#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
124#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
125#[serde(rename_all = "camelCase")]
126#[serde(deny_unknown_fields)]
127pub struct Outfitting {
128    id: Option<String>,
129    name: String,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
133#[serde(untagged)]
134#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
135pub enum Name {
136    String(String),
137    Number(u64),
138}
139
140impl std::fmt::Display for Name {
141    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
142        match self {
143            Name::String(s) => write!(f, "{}", s),
144            Name::Number(n) => write!(f, "{}", n),
145        }
146    }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
150#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
151#[serde(rename_all = "camelCase")]
152#[serde(deny_unknown_fields)]
153pub struct Ship {
154    id: u64,
155    name: Name,
156}
157
158#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
159#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
160#[serde(rename_all = "camelCase")]
161#[serde(deny_unknown_fields)]
162pub struct StationBody {
163    pub id: u64,
164    // Attributes
165    pub latitude: Option<f32>,
166    pub longitude: Option<f32>,
167    pub name: String,
168}
169
170#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, EnumIter, VariantCount)]
171#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
172#[serde(deny_unknown_fields)]
173pub enum StationType {
174    // Orbital Large
175    #[serde(rename = "Ocellus Starport")]
176    OcellusStarport,
177    #[serde(rename = "Orbis Starport")]
178    OrbisStarport,
179    #[serde(rename = "Coriolis Starport")]
180    CoriolisStarport,
181    #[serde(rename = "Asteroid base")]
182    AsteroidBase,
183    #[serde(rename = "Mega ship")]
184    MegaShip,
185    // Orbital small
186    Outpost,
187    // Planetary
188    #[serde(rename = "Planetary Port")]
189    PlanetaryPort,
190    #[serde(rename = "Planetary Outpost")]
191    PlanetaryOutpost,
192    #[serde(rename = "Odyssey Settlement")]
193    OdysseySettlement,
194    // Fleet Carrier
195    #[serde(rename = "Fleet Carrier")]
196    FleetCarrier,
197}
198
199display_via_serde!(StationType);
200
201#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
202#[cfg_attr(feature = "type_hash", derive(type_hash::TypeHash))]
203#[serde(rename_all = "camelCase")]
204#[serde(deny_unknown_fields)]
205pub struct UpdateTime {
206    #[serde(with = "date_format")]
207    #[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
208    pub information: DateTime<Utc>,
209    #[serde(with = "date_format_opt")]
210    #[serde(default = "option_none")]
211    #[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
212    pub market: Option<DateTime<Utc>>,
213    #[serde(with = "date_format_opt")]
214    #[serde(default = "option_none")]
215    #[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
216    pub outfitting: Option<DateTime<Utc>>,
217    #[serde(with = "date_format_opt")]
218    #[serde(default = "option_none")]
219    #[cfg_attr(feature = "type_hash", type_hash(foreign_type))]
220    pub shipyard: Option<DateTime<Utc>>,
221}
222
223fn option_none<T>() -> Option<T> {
224    None
225}