messy filter support

This commit is contained in:
Nicholas Orlowsky 2026-02-16 18:49:47 -05:00
parent 6773e6ae30
commit b7ec6a292f
No known key found for this signature in database
GPG key ID: A9F3BA4C0AA7A70B
15 changed files with 445 additions and 103 deletions

View file

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(sqlx::Type, Serialize, Deserialize, PartialEq, Debug, Clone, Copy, Eq)]
#[derive(sqlx::Type, Serialize, Deserialize, PartialEq, Debug, Clone, Copy, Eq, PartialOrd, Ord)]
#[sqlx(type_name = "septa_direction_type", rename_all = "snake_case")]
pub enum CardinalDirection {
Northbound,

View file

@ -1,3 +1,5 @@
use std::cmp::Ordering;
use serde::{Deserialize, Serialize};
#[derive(sqlx::Type, Serialize, Deserialize, PartialEq, Debug, Clone)]
@ -16,7 +18,28 @@ pub struct Route {
pub short_name: String,
pub color_hex: String,
pub route_type: RouteType,
pub id: String
pub id: String,
pub directions: Vec<crate::direction::Direction>
}
impl PartialEq for Route {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Route {}
impl Ord for Route {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl PartialOrd for Route {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.id.cmp(&other.id))
}
}

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use chrono::{Datelike, Days, TimeZone, Weekday};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Serialize, Serializer, de::Error};
use crate::{direction::Direction, route::Route, stop::Platform};
@ -93,6 +93,82 @@ impl CalendarDay {
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SeatAvailability {
Full = 4,
CrushedStandingRoomOnly = 3,
FewSeats = 2,
ManySeats = 1,
Empty = 0
}
impl<'de> Deserialize<'de> for SeatAvailability {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de> {
let string = String::deserialize(deserializer)?;
return match SeatAvailability::from_string(&string) {
Some(x) => Ok(x),
None => Err(serde::de::Error::custom(""))
};
}
}
impl Serialize for SeatAvailability {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_str())
}
}
impl SeatAvailability {
pub fn iter() -> Vec<SeatAvailability> {
vec![Self::Empty, Self::ManySeats, Self::FewSeats, Self::CrushedStandingRoomOnly, Self::Full]
}
pub fn to_string(&self) -> String {
String::from(match &self {
Self::Full => "FULL",
Self::CrushedStandingRoomOnly => "CRUSHED_STANDING_ROOM_ONLY",
Self::FewSeats => "FEW_SEATS_AVAILABLE",
Self::ManySeats => "MANY_SEATS_AVAILABLE",
Self::Empty => "EMPTY",
})
}
pub fn to_human_string(&self) -> String {
String::from(match &self {
Self::Full => "Full",
Self::CrushedStandingRoomOnly => "Sardines",
Self::FewSeats => "Few seats",
Self::ManySeats => "Many seats",
Self::Empty => "Empty"
})
}
pub fn from_string(str: &String) -> Option<SeatAvailability> {
match str.as_str() {
"FULL" => Some(Self::Full),
"CRUSHED_STANDING_ROOM_ONLY" => Some(Self::CrushedStandingRoomOnly),
"FEW_SEATS_AVAILABLE" => Some(Self::FewSeats),
"MANY_SEATS_AVAILABLE" => Some(Self::ManySeats),
"EMPTY" => Some(Self::Empty),
_ => None
}
}
pub fn from_opt_string(opt_str: &Option<String>) -> Option<SeatAvailability> {
if let Some(str) = &opt_str {
Self::from_string(str)
} else {
None
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LiveTrip {
pub delay: f64,
@ -102,7 +178,7 @@ pub struct LiveTrip {
pub latitude: Option<f64>,
pub longitude: Option<f64>,
pub heading: Option<f64>,
pub seat_availability: Option<String>,
pub seat_availability: Option<SeatAvailability>,
pub trip_id: String,
pub route_id: String,
}