Skip to content

Commit

Permalink
feat: Implemented ts-rs
Browse files Browse the repository at this point in the history
  • Loading branch information
wd7bxscience committed May 15, 2024
1 parent a253d7c commit 2537e30
Show file tree
Hide file tree
Showing 14 changed files with 300 additions and 200 deletions.
319 changes: 182 additions & 137 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ tungstenite = "0.21.0"
crossbeam-channel = "0.5.12"
gtfs-structures = { version="0.41.2", default-features=false, features=[] }
chrono = { version="0.4.38", features = ["alloc"]}
ts-rs = "8.1"
rgb = { version="0.8.37", features = ["serde"]}

[build-dependencies]
prost-build = { version = "0.12.3" }
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The webpage can be found at http:https://localhost:3000/ after deploying.
Open 2 terminals and run the following commands.

```bash
cargo test
cargo run
```

Expand All @@ -44,6 +45,7 @@ Open 2 terminals and run the following commands.
> Note: `start` is a command only found on Windows.
```bash
cargo test
cargo build --release
start .\target\release\transit-board.exe
```
Expand Down
30 changes: 15 additions & 15 deletions src/bus_stop_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct BusStopHandler {
api_key: Arc<String>,
pub stop_ids: Vec<String>,
pub trips: Vec<Vehicle>,
pub routes: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
pub destinations: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
}

impl BusStopHandler {
Expand All @@ -29,7 +29,7 @@ impl BusStopHandler {

pub fn refresh(&mut self) {
let mut trips: Vec<Vehicle> = Default::default();
let mut routes: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>> = Default::default();
let mut destinations: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>> = Default::default();

// If we cannot get a duration from the UNIX_EPOCH, or make that into an i64, we have problems.
// Should not fail else we can't get any time data at all.
Expand Down Expand Up @@ -105,18 +105,18 @@ impl BusStopHandler {
});

// Input data into routes
if !routes.contains_key(route_id) {
routes.insert(route_id.to_owned(), BTreeMap::new());
if !destinations.contains_key(route_id) {
destinations.insert(route_id.to_owned(), BTreeMap::new());
}
if !routes.get(route_id).unwrap().contains_key(destination_id) {
if !destinations.get(route_id).unwrap().contains_key(destination_id) {
// Key must exist because of above line
routes
destinations
.get_mut(route_id) // Key must exist for same reason above
.unwrap()
.insert(destination_id.to_owned(), Vec::new());
};

routes
destinations
.get_mut(route_id) // Key exists
.unwrap()
.get_mut(destination_id)
Expand Down Expand Up @@ -145,7 +145,7 @@ impl BusStopHandler {
});

self.trips = trips;
self.routes = routes;
self.destinations = destinations;
}

pub fn serialize(&self) -> Stop {
Expand All @@ -163,12 +163,12 @@ impl BusStopHandler {
Stop {
name: name.to_owned(),
trips: self.trips.to_owned(),
routes: self.routes.to_owned(),
destinations: self.destinations.to_owned(),
}
}

pub fn predict(&mut self) {
self.routes.clear();
self.destinations.clear();

for trip in &mut self.trips {
trip.minutes_until_arrival -= 1;
Expand All @@ -178,23 +178,23 @@ impl BusStopHandler {
}

// All the unwraps are verified between lines 161-191
if !self.routes.contains_key(&trip.route_id) {
self.routes.insert(trip.route_id.to_owned(), BTreeMap::new());
if !self.destinations.contains_key(&trip.route_id) {
self.destinations.insert(trip.route_id.to_owned(), BTreeMap::new());
}
if !self
.routes
.destinations
.get(&trip.route_id)
.unwrap()
.contains_key(&trip.destination_id)
{
self
.routes
.destinations
.get_mut(&trip.route_id)
.unwrap()
.insert(trip.destination_id.to_owned(), Vec::new());
};
self
.routes
.destinations
.get_mut(&trip.route_id)
.unwrap()
.get_mut(&trip.destination_id)
Expand Down
20 changes: 8 additions & 12 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,38 @@
use std::sync::{Arc, RwLock};

use serde::{Deserialize, Serialize};
use ts_rs::TS;

use crate::{
bus_stop_handler::BusStopHandler, feed_handler::FeedHandler, service_alert_handler::ServiceAlertHandler,
subway_stop_handler::SubwayStopHandler,
};

#[derive(Debug, Serialize, Deserialize, Default)]
#[derive(Debug, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Config {
subway: Vec<StopConfig>,
bus: Vec<StopConfig>,
}

#[derive(Debug, Serialize, Deserialize, Default)]
pub struct StopConfig {
pub stop_ids: Vec<String>,
pub walk_time: i32,
subway: Vec<Vec<String>>,
bus: Vec<Vec<String>>,
}

impl Config {
pub fn new(subway: Vec<StopConfig>, bus: Vec<StopConfig>) -> Self {
pub fn new(subway: Vec<Vec<String>>, bus: Vec<Vec<String>>) -> Self {
Self { subway, bus }
}

pub fn get_subway_handlers(&self, feed_data: Arc<RwLock<FeedHandler>>) -> Vec<SubwayStopHandler> {
self
.subway
.iter()
.map(|a| SubwayStopHandler::new(feed_data.to_owned(), a.stop_ids.to_owned()))
.map(|a| SubwayStopHandler::new(feed_data.to_owned(), a.to_owned()))
.collect()
}

pub fn get_bus_handlers(&self, api_key: Arc<String>, feed_data: Arc<RwLock<FeedHandler>>) -> Vec<BusStopHandler> {
self
.bus
.iter()
.map(|a| BusStopHandler::new(feed_data.to_owned(), api_key.to_owned(), a.stop_ids.to_owned()))
.map(|a| BusStopHandler::new(feed_data.to_owned(), api_key.to_owned(), a.to_owned()))
.collect()
}

Expand Down
31 changes: 26 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use ts_rs::TS;

use serde::{Deserialize, Serialize};

Expand All @@ -13,7 +14,8 @@ pub mod gtfsrt {
include!(concat!(env!("OUT_DIR"), "/transit_realtime.rs"));
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Vehicle {
pub route_id: String,
pub route_name: String,
Expand All @@ -22,16 +24,35 @@ pub struct Vehicle {
pub minutes_until_arrival: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Stop {
pub name: String,
pub trips: Vec<Vehicle>,
pub routes: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
pub destinations: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Alert {
pub route_id: String,
pub sort_order: i32,
pub header_text: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Route {
pub route_id: String,
pub route_name: String,
pub route_color: String,
pub route_text_color: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
#[ts(export)]
pub struct Export {
pub stops_realtime: BTreeMap<String, Stop>,
pub service_alerts_realtime: Vec<Alert>,
pub routes_static: HashMap<String, Route>,
}
40 changes: 24 additions & 16 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ use std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;

use gtfs_structures::Route;
use serde::{Deserialize, Serialize};
use transit_board::config::Config;
use transit_board::feed_handler::FeedHandler;
use transit_board::{Alert, Stop};
use transit_board::{Export, Route, Stop};
use tungstenite::protocol::frame::coding::CloseCode;
use tungstenite::protocol::CloseFrame;
use tungstenite::Message;
use tungstenite::{protocol::CloseFrame, Message};

fn main() {
dotenvy::dotenv().expect("Dotenv not found, check that it exists or else board will not be able to use some MTA data (bus data)\n.env file should be located in the directory where you call the server, or a parent directory");
Expand Down Expand Up @@ -96,16 +93,34 @@ fn main() {
// If lock cannot be acquired, then the data is no longer accessible
// Application should crash on RwLock poisining
let feed_data = data.read().unwrap();
let mut routes_static = feed_data.subway_static_feed.routes.clone();
let mut routes = feed_data.subway_static_feed.routes.clone();

// Combines bus static feed data into subway static feed data
for gtfs in feed_data.bus_static_feed.iter() {
for (key, value) in gtfs.routes.iter() {
routes_static.insert(key.to_owned(), value.to_owned());
routes.insert(key.to_owned(), value.to_owned());
}
}

let data = InfoJson {
let mut routes_static: HashMap<String, Route> = Default::default();
for (key, value) in routes.iter() {
let route = Route {
route_id: value.id.to_owned(),
route_name: value.short_name.as_ref().unwrap().to_owned(),
route_color: format!("{:02X}{:02X}{:02X}", value.color.r, value.color.g, value.color.b)
.as_str()
.to_owned(),
route_text_color: format!(
"{:02X}{:02X}{:02X}",
value.text_color.r, value.text_color.g, value.text_color.b
)
.as_str()
.to_owned(),
};
routes_static.insert(key.to_owned(), route.to_owned());
}

let data = Export {
stops_realtime: stops_map.to_owned(),
service_alerts_realtime: service_alerts.subway.to_owned(),
routes_static: routes_static.to_owned(),
Expand All @@ -116,7 +131,7 @@ fn main() {
Ok(a) => a,
Err(_) => {
eprintln!("Sent blank data, could not serialize data");
serde_json::to_string(&InfoJson::default()).unwrap()
serde_json::to_string(&Export::default()).unwrap()
} // Send blank data
};
let message = Message::Text(data);
Expand All @@ -131,10 +146,3 @@ fn main() {
});
}
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
struct InfoJson {
stops_realtime: BTreeMap<String, Stop>,
service_alerts_realtime: Vec<Alert>,
routes_static: HashMap<String, Route>,
}
30 changes: 15 additions & 15 deletions src/subway_stop_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct SubwayStopHandler {
feed_data: Arc<RwLock<FeedHandler>>,
pub stop_ids: Vec<String>,
pub trips: Vec<Vehicle>,
pub routes: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
pub destinations: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>>,
}

impl SubwayStopHandler {
Expand All @@ -31,7 +31,7 @@ impl SubwayStopHandler {
}

let mut trips: Vec<Vehicle> = Default::default();
let mut routes: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>> = Default::default();
let mut destinations: BTreeMap<String, BTreeMap<String, Vec<Vehicle>>> = Default::default();

// Crash if UNIX_EPOCH fails to convert to i64
let current_time = i64::try_from(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()).unwrap();
Expand Down Expand Up @@ -88,16 +88,16 @@ impl SubwayStopHandler {

// All data from lines 90-110 are verified via the if statements
// Input data into routes
if !routes.contains_key(route_id) {
routes.insert(route_id.to_owned(), BTreeMap::new());
if !destinations.contains_key(route_id) {
destinations.insert(route_id.to_owned(), BTreeMap::new());
}
if !routes.get(route_id).unwrap().contains_key(destination_id) {
routes
if !destinations.get(route_id).unwrap().contains_key(destination_id) {
destinations
.get_mut(route_id)
.unwrap()
.insert(destination_id.to_owned(), Vec::new());
};
routes
destinations
.get_mut(route_id)
.unwrap()
.get_mut(destination_id)
Expand Down Expand Up @@ -126,7 +126,7 @@ impl SubwayStopHandler {
});

self.trips = trips;
self.routes = routes;
self.destinations = destinations;
}

pub fn serialize(&self) -> Stop {
Expand All @@ -143,12 +143,12 @@ impl SubwayStopHandler {
.unwrap() // A stop should have name
.to_string(),
trips: self.trips.to_owned(),
routes: self.routes.to_owned(),
destinations: self.destinations.to_owned(),
}
}

pub fn predict(&mut self) {
self.routes.clear();
self.destinations.clear();

for trip in &mut self.trips {
trip.minutes_until_arrival -= 1;
Expand All @@ -158,23 +158,23 @@ impl SubwayStopHandler {
}

// All the unwraps are verified between lines 161-191
if !self.routes.contains_key(&trip.route_id) {
self.routes.insert(trip.route_id.to_owned(), BTreeMap::new());
if !self.destinations.contains_key(&trip.route_id) {
self.destinations.insert(trip.route_id.to_owned(), BTreeMap::new());
}
if !self
.routes
.destinations
.get(&trip.route_id)
.unwrap()
.contains_key(&trip.destination_id)
{
self
.routes
.destinations
.get_mut(&trip.route_id)
.unwrap()
.insert(trip.destination_id.to_owned(), Vec::new());
};
self
.routes
.destinations
.get_mut(&trip.route_id)
.unwrap()
.get_mut(&trip.destination_id)
Expand Down
3 changes: 3 additions & 0 deletions types/Alert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export type Alert = { route_id: string, sort_order: number, header_text: string, };
Loading

0 comments on commit 2537e30

Please sign in to comment.