gatelogue_types/node/
air.rs

1use 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}