Skip to main content

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}
17_from_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!(flights, AirFlight, "../sql/air/airline_flights.sql");
25    _get_derived_vec!(gates, AirGate, "../sql/air/airline_gates.sql");
26    _get_derived_vec!(airports, AirAirport, "../sql/air/airline_airports.sql");
27}
28
29node_type!(located AirAirport);
30impl AirAirport {
31    _get_column!("AirAirport", code, String);
32    _get_set!("AirAirportNames", names, "name", String);
33    _get_column!("AirAirport", link, Option<String>);
34    _get_set!("AirAirportModes", modes, "mode", AirMode);
35    _get_derived_vec!(gates, AirGate, "../sql/air/airport_gates.sql");
36}
37
38node_type!(AirGate);
39impl AirGate {
40    _get_column!("AirGate", code, Option<String>);
41    _get_column!("AirGate", airport, AirAirport);
42    _get_column!("AirGate", airline, Option<AirAirline>);
43    _get_column!("AirGate", width, Option<u32>);
44    _get_column!("AirGate", mode, AirMode);
45    _get_derived_vec!(
46        flights_from_here,
47        AirFlight,
48        "../sql/air/gate_flights_from_here.sql"
49    );
50    _get_derived_vec!(
51        flights_to_here,
52        AirFlight,
53        "../sql/air/gate_flights_to_here.sql"
54    );
55}
56
57node_type!(AirFlight);
58impl AirFlight {
59    _get_column!("AirFlight", airline, AirAirline);
60    _get_column!("AirFlight", code, String);
61    _get_column!("AirFlight", from, AirGate);
62    _get_column!("AirFlight", to, AirGate);
63    _get_column!("AirFlight", aircraft, Option<Aircraft>);
64    _get_column!("AirFlight", duration, Option<u32>);
65}
66
67#[macro_export]
68macro_rules! get_aircraft_column {
69    ($column_name:ident, $ColTy:ty) => {
70        pub fn $column_name(self, gd: &$crate::GD) -> $crate::error::Result<$ColTy> {
71            gd.0.query_one(
72                concat!(
73                    "SELECT \"",
74                    stringify!($column_name),
75                    "\" FROM Aircraft WHERE name = ?"
76                ),
77                (&self.name(),),
78                |a| a.get(0),
79            )
80            .map_err(|e| {
81                if e == rusqlite::Error::QueryReturnedNoRows {
82                    $crate::error::Error::NoAircraft(self.name().clone())
83                } else {
84                    e.into()
85                }
86            })
87        }
88    };
89}
90
91#[derive(Clone, PartialEq, Eq, Debug)]
92pub struct Aircraft(pub(crate) String);
93impl FromSql for Aircraft {
94    fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
95        Ok(Self(value.as_str()?.into()))
96    }
97}
98
99impl Aircraft {
100    #[must_use]
101    pub const fn name(&self) -> &String {
102        &self.0
103    }
104    get_aircraft_column!(manufacturer, String);
105    get_aircraft_column!(width, u32);
106    get_aircraft_column!(height, u32);
107    get_aircraft_column!(length, u32);
108    get_aircraft_column!(mode, AirMode);
109}