Skip to content

Commit

Permalink
refactor/docs/feat: remove tripdescriptors and stuff (#2)
Browse files Browse the repository at this point in the history
* feat: add start_time and start_date to Vehicle

* refactor: remove TripDescriptors

* refactor: *really* remove TripDescriptor, introduce GtfsRealtime

* docs: add minimal README example
  • Loading branch information
bklebe authored Oct 24, 2023
1 parent 4b4afd0 commit e8232e9
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 171 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@
# transit-query
`cargo run`
## e.g. get crowding information on every vehicle and their lat/long
```graphql
{
Vehicle {
lead_car: label @output
latitude @output
longitude @output

trip_descriptor {
route {
route: long_name @output
}
}

multi_carriage_details {
label @output
occupancy_percentage @output
occupancy_status @output
}
}
}

```
10 changes: 8 additions & 2 deletions query.gql
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
{
Vehicle {
stop {
stop: name @output
lead_car: label @output
latitude @output
longitude @output

trip_descriptor {
route {
route: long_name @output
}
}

multi_carriage_details {
Expand Down
15 changes: 6 additions & 9 deletions src/adapter/adapter_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ use std::sync::{Arc, OnceLock};

use trustfall::{
provider::{
resolve_coercion_using_schema, resolve_property_with, AsVertex,
ContextIterator, ContextOutcomeIterator, EdgeParameters, ResolveEdgeInfo, ResolveInfo,
Typename, VertexIterator,
resolve_coercion_using_schema, resolve_property_with, AsVertex, ContextIterator,
ContextOutcomeIterator, EdgeParameters, ResolveEdgeInfo, ResolveInfo, Typename,
VertexIterator,
},
FieldValue, Schema,
};

use crate::{gtfs_schedule::GtfsSchedule, TripUpdates, VehiclePositions};
use crate::{
gtfs_realtime::TripUpdates, gtfs_realtime::VehiclePositions, gtfs_schedule::GtfsSchedule,
};

use super::vertex::Vertex;

Expand Down Expand Up @@ -95,11 +97,6 @@ impl<'a> trustfall::provider::Adapter<'a> for Adapter<'a> {
property_name.as_ref(),
resolve_info,
),
"TripDescriptor" => super::properties::resolve_trip_descriptor_property(
contexts,
property_name.as_ref(),
resolve_info,
),
"Vehicle" => super::properties::resolve_vehicle_property(
contexts,
property_name.as_ref(),
Expand Down
25 changes: 4 additions & 21 deletions src/adapter/edges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub(super) fn resolve_vehicle_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
match edge_name {
"stop" => vehicle::stop(&schedule.stops, contexts, resolve_info),
"trip" => vehicle::trip(&schedule.trips, contexts, resolve_info),
"trip_descriptor" => vehicle::trip_descriptor(contexts, resolve_info),
"trip_descriptor" => vehicle::trip(&schedule.trips, contexts, resolve_info),
"multi_carriage_details" => vehicle::multi_carriage_details(contexts, resolve_info),
_ => {
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Vehicle'")
Expand All @@ -94,8 +94,8 @@ mod vehicle {
};

use crate::{
gtfs_schedule::{ScheduledTrip, Stop},
VehiclePosition,
gtfs_realtime::VehiclePosition,
gtfs_schedule::{Stop, Trip},
};

use super::super::vertex::Vertex;
Expand Down Expand Up @@ -125,7 +125,7 @@ mod vehicle {
}

pub(super) fn trip<'a, V: AsVertex<Vertex<'a>> + 'a>(
trips: &'a [ScheduledTrip],
trips: &'a [Trip],
contexts: ContextIterator<'a, V>,
_resolve_info: &ResolveEdgeInfo,
) -> ContextOutcomeIterator<'a, V, VertexIterator<'a, Vertex<'a>>> {
Expand All @@ -148,23 +148,6 @@ mod vehicle {
})
}

pub(super) fn trip_descriptor<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
_resolve_info: &ResolveEdgeInfo,
) -> ContextOutcomeIterator<'a, V, VertexIterator<'a, Vertex<'a>>> {
resolve_neighbors_with(contexts, |vertex| {
let vertex: &VehiclePosition = vertex
.as_vehicle()
.expect("conversion failed, vertex was not a Vehicle");

if let Some(trip_descriptor) = &vertex.trip {
return Box::new(iter::once(Vertex::TripDescriptor(trip_descriptor)));
} else {
Box::new(std::iter::empty())
}
})
}

pub(super) fn multi_carriage_details<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
_resolve_info: &ResolveEdgeInfo,
Expand Down
57 changes: 26 additions & 31 deletions src/adapter/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,6 @@ pub(super) fn resolve_trip_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
}
}

pub(super) fn resolve_trip_descriptor_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, V, FieldValue> {
match property_name {
"id" => resolve_property_with(contexts, field_property!(as_trip_descriptor, trip_id)),
"direction_id" => {
resolve_property_with(contexts, field_property!(as_trip_descriptor, direction_id))
}
"route_id" => {
resolve_property_with(contexts, field_property!(as_trip_descriptor, route_id))
}
"start_time" => {
resolve_property_with(contexts, field_property!(as_trip_descriptor, start_time))
}
"start_date" => {
resolve_property_with(contexts, field_property!(as_trip_descriptor, start_date))
}
"schedule_relationship" => resolve_property_with(
contexts,
field_property!(as_trip_descriptor, schedule_relationship),
),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'TripDescriptor'"
)
}
}
}

pub(super) fn resolve_vehicle_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
property_name: &str,
Expand All @@ -102,6 +71,12 @@ pub(super) fn resolve_vehicle_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
"current_stop_sequence" => {
resolve_property_with(contexts, field_property!(as_vehicle, current_stop_sequence))
}
"direction_id" => resolve_property_with(
contexts,
field_property!(as_vehicle, trip, {
trip.as_ref().map(|t| t.direction_id).into()
}),
),
"label" => resolve_property_with(
contexts,
field_property!(as_vehicle, vehicle, { vehicle.label.clone().into() }),
Expand All @@ -118,6 +93,26 @@ pub(super) fn resolve_vehicle_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
FieldValue::Float64(position.longitude)
}),
),
"schedule_relationship" => resolve_property_with(
contexts,
field_property!(as_vehicle, trip, {
trip.as_ref()
.map(|t| t.schedule_relationship.clone())
.into()
}),
),
"start_time" => resolve_property_with(
contexts,
field_property!(as_vehicle, trip, {
trip.as_ref().map(|t| t.start_time.clone()).into()
}),
),
"start_date" => resolve_property_with(
contexts,
field_property!(as_vehicle, trip, {
trip.as_ref().map(|t| t.start_date.clone()).into()
}),
),
"occupancy_percentage" => {
resolve_property_with(contexts, field_property!(as_vehicle, occupancy_percentage))
}
Expand Down
15 changes: 4 additions & 11 deletions src/adapter/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,16 @@ type RootSchemaQuery {
}

type Trip {
id: String!
direction_id: Int!
trip_headsign: String!

route: Route
vehicle: Vehicle
}

type TripDescriptor {
id: String!
direction_id: Int
trip_headsign: String
start_time: String
start_date: String
schedule_relationship: String
timestamp: Int

route: Route
vehicle: Vehicle
vehicles: [Vehicle!]
}

type Vehicle {
Expand All @@ -77,7 +70,7 @@ type Vehicle {

stop: Stop
trip: Trip
trip_descriptor: TripDescriptor
trip_descriptor: Trip
}

type CarriageDetails {
Expand Down
8 changes: 5 additions & 3 deletions src/adapter/vertex.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::gtfs_schedule::{Route, ScheduledTrip, Stop};
use crate::{CarriageDetails, TripDescriptor, VehiclePosition};
use crate::{
gtfs_realtime::{CarriageDetails, TripDescriptor, VehiclePosition},
gtfs_schedule::{Route, Stop, Trip},
};

#[non_exhaustive]
#[derive(Debug, Clone, trustfall::provider::TrustfallEnumVertex)]
pub enum Vertex<'a> {
Route(&'a Route),
Stop(&'a Stop),
Trip(&'a ScheduledTrip),
Trip(&'a Trip),
TripDescriptor(&'a TripDescriptor),
Vehicle(&'a VehiclePosition),
CarriageDetails(&'a CarriageDetails),
Expand Down
90 changes: 90 additions & 0 deletions src/gtfs_realtime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use serde::{Deserialize, Serialize};

use crate::gtfs_schedule::Trip;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub(crate) struct Position {
bearing: i64,
pub(crate) latitude: f64,
pub(crate) longitude: f64,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TripDescriptor {
pub(crate) direction_id: i64,
route_id: String,
pub(crate) schedule_relationship: Option<String>,
pub(crate) start_date: Option<String>,
pub(crate) start_time: Option<String>,
pub(crate) trip_id: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CarriageDetails {
carriage_sequence: i64,
pub(crate) id: Option<String>,
pub(crate) label: String,
pub(crate) occupancy_percentage: i64,
pub(crate) occupancy_status: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub(crate) struct VehicleDescriptor {
pub(crate) id: String,
pub(crate) label: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VehiclePosition {
pub(crate) current_status: Option<String>,
pub(crate) current_stop_sequence: Option<i64>,
pub(crate) occupancy_percentage: Option<i64>,
pub(crate) occupancy_status: Option<String>,
pub(crate) multi_carriage_details: Option<Vec<CarriageDetails>>,
pub(crate) position: Position,
pub(crate) stop_id: Option<String>,
pub(crate) timestamp: i64,
pub(crate) trip: Option<Trip>,
pub(crate) vehicle: VehicleDescriptor,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub(crate) struct VehicleEntity {
id: String,
pub(crate) vehicle: VehiclePosition,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VehiclePositions {
pub(crate) entity: Vec<VehicleEntity>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub(crate) struct TripEntity {
id: String,
trip_update: TripUpdate,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
struct StopTimeEvent {
time: i64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct StopTimeUpdate {
arrival: Option<StopTimeEvent>,
departure: Option<StopTimeEvent>,
stop_id: String,
stop_sequence: i64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct TripUpdate {
stop_time_update: Option<Vec<StopTimeUpdate>>,
timestamp: Option<i64>,
trip: Trip,
vehicle: Option<VehicleDescriptor>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TripUpdates {
pub(crate) entity: Vec<TripEntity>,
}
15 changes: 9 additions & 6 deletions src/gtfs_schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub(crate) struct GtfsSchedule {
pub routes: Vec<Route>,
pub stops: Vec<Stop>,
pub trips: Vec<ScheduledTrip>,
pub trips: Vec<Trip>,
}

impl GtfsSchedule {
Expand Down Expand Up @@ -55,12 +55,15 @@ pub struct Stop {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ScheduledTrip {
pub struct Trip {
pub(super) route_id: String,
pub(super) service_id: String,
pub(super) service_id: Option<String>,
pub(super) trip_id: String,
pub(super) trip_headsign: String,
pub(super) trip_headsign: Option<String>,
pub(super) direction_id: i64,
pub(super) shape_id: String,
pub(super) block_id: String,
pub(super) shape_id: Option<String>,
pub(super) block_id: Option<String>,
pub(super) start_time: Option<String>,
pub(super) start_date: Option<String>,
pub(super) schedule_relationship: Option<String>,
}
Loading

0 comments on commit e8232e9

Please sign in to comment.