gatelogue_types/node/
air.rs1use rusqlite::types::{FromSql, FromSqlResult, ValueRef};
2use strum_macros::EnumString;
3
4use crate::{from_sql_for_enum, get_column, get_derived_vec, get_set, node_type, util::ID};
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug, EnumString)]
7pub enum AirMode {
8 #[strum(serialize = "helicopter")]
9 Helicopter,
10 #[strum(serialize = "seaplane")]
11 Seaplane,
12 #[strum(serialize = "warp plane")]
13 WarpPlane,
14 #[strum(serialize = "traincarts plane")]
15 TrainCartsPlane,
16}
17from_sql_for_enum!(AirMode);
18
19node_type!(AirAirline);
20impl AirAirline {
21 get_column!("AirAirline", name, String);
22 get_column!("AirAirline", link, Option<String>);
23
24 get_derived_vec!(
25 flights,
26 AirFlight,
27 "SELECT i FROM AirFlight WHERE airline = ?"
28 );
29 get_derived_vec!(
30 gates,
31 AirGate,
32 concat!(
33 "SELECT i FROM AirGate WHERE airline = ? ",
34 "UNION SELECT \"from\" AS i FROM AirFlight WHERE airline = ? ",
35 "UNION SELECT \"to\" AS i FROM AirFlight WHERE airline = ?"
36 )
37 );
38 get_derived_vec!(airports, AirAirport, concat!("SELECT DISTINCT airport FROM AirGate WHERE airline = ? ",
39 "UNION SELECT DISTINCT airport FROM AirFlight LEFT JOIN AirGate on AirGate.i = \"from\" WHERE AirFlight.airline = ? ",
40 "UNION SELECT DISTINCT airport FROM AirFlight LEFT JOIN AirGate on AirGate.i = \"to\" WHERE AirFlight.airline = ?"));
41}
42
43node_type!(located AirAirport);
44impl AirAirport {
45 get_column!("AirAirport", code, String);
46 get_set!("AirAirportNames", names, "name", String);
47 get_column!("AirAirport", link, Option<String>);
48 get_set!("AirAirportModes", modes, "mode", AirMode);
49 get_derived_vec!(gates, AirGate, "SELECT i FROM AirGate WHERE airport = ?");
50}
51
52node_type!(AirGate);
53impl AirGate {
54 get_column!("AirGate", code, Option<String>);
55 get_column!("AirGate", airport, AirAirport);
56 get_column!("AirGate", airline, Option<AirAirline>);
57 get_column!("AirGate", width, Option<u32>);
58 get_column!("AirGate", mode, AirMode);
59 get_derived_vec!(
60 flights_from_here,
61 AirFlight,
62 "SELECT i FROM AirFlight WHERE \"from\" = ?"
63 );
64 get_derived_vec!(
65 flights_to_here,
66 AirFlight,
67 "SELECT i FROM AirFlight WHERE \"to\" = ?"
68 );
69}
70
71node_type!(AirFlight);
72impl AirFlight {
73 get_column!("AirFlight", airline, AirAirline);
74 get_column!("AirFlight", code, String);
75 get_column!("AirFlight", from, AirGate);
76 get_column!("AirFlight", to, AirGate);
77 get_column!("AirFlight", aircraft, Option<Aircraft>);
78}
79
80#[macro_export]
81macro_rules! get_aircraft_column {
82 ($column_name:ident, $ColTy:ty) => {
83 pub fn $column_name(self, gd: &$crate::GD) -> $crate::error::Result<$ColTy> {
84 gd.0.query_one(
85 concat!(
86 "SELECT \"",
87 stringify!($column_name),
88 "\" FROM Aircraft WHERE name = ?"
89 ),
90 (&self.name(),),
91 |a| a.get(0),
92 )
93 .map_err(|e| {
94 if e == rusqlite::Error::QueryReturnedNoRows {
95 $crate::error::Error::NoAircraft(self.name().clone())
96 } else {
97 e.into()
98 }
99 })
100 }
101 };
102}
103
104#[derive(Clone, PartialEq, Eq, Debug)]
105pub struct Aircraft(pub(crate) String);
106impl FromSql for Aircraft {
107 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
108 Ok(Self(value.as_str()?.into()))
109 }
110}
111
112impl Aircraft {
113 #[must_use]
114 pub const fn name(&self) -> &String {
115 &self.0
116 }
117 get_aircraft_column!(manufacturer, String);
118 get_aircraft_column!(width, u32);
119 get_aircraft_column!(height, u32);
120 get_aircraft_column!(length, u32);
121 get_aircraft_column!(mode, AirMode);
122}