diff --git a/editoast/editoast_schemas/src/train_schedule.rs b/editoast/editoast_schemas/src/train_schedule.rs index 650c6ac51bc..fad6191fcc1 100644 --- a/editoast/editoast_schemas/src/train_schedule.rs +++ b/editoast/editoast_schemas/src/train_schedule.rs @@ -7,6 +7,7 @@ pub use schedule_item::ReceptionSignal; pub use schedule_item::ScheduleItem; mod path_item; +pub use path_item::OperationalPointIdentifier; pub use path_item::PathItem; pub use path_item::PathItemLocation; diff --git a/editoast/editoast_schemas/src/train_schedule/path_item.rs b/editoast/editoast_schemas/src/train_schedule/path_item.rs index 0ae69acb9ef..0ce9ecf64d9 100644 --- a/editoast/editoast_schemas/src/train_schedule/path_item.rs +++ b/editoast/editoast_schemas/src/train_schedule/path_item.rs @@ -32,6 +32,16 @@ pub struct PathItem { #[serde(untagged, deny_unknown_fields)] pub enum PathItemLocation { TrackOffset(#[schema(inline)] TrackOffset), + OperationalPointReference { + reference: OperationalPointIdentifier, + track: Option, + track_label: Option, + }, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema, Hash)] +#[serde(untagged, deny_unknown_fields)] +pub enum OperationalPointIdentifier { OperationalPointId { /// The object id of an operational point #[schema(inline)] diff --git a/editoast/editoast_schemas/src/train_schedule/train_schedule_base.rs b/editoast/editoast_schemas/src/train_schedule/train_schedule_base.rs index d01d0642d03..3feff062634 100644 --- a/editoast/editoast_schemas/src/train_schedule/train_schedule_base.rs +++ b/editoast/editoast_schemas/src/train_schedule/train_schedule_base.rs @@ -162,6 +162,7 @@ mod tests { use serde_json::from_str; use serde_json::to_string; + use crate::train_schedule::path_item::OperationalPointIdentifier::OperationalPointId; use crate::train_schedule::schedule_item::ReceptionSignal; use crate::train_schedule::Margins; use crate::train_schedule::PathItemLocation; @@ -180,8 +181,12 @@ mod tests { /// Test deserialize an invalid train schedule #[test] fn deserialize_duplicate_path_id_train_schedule() { - let location = PathItemLocation::OperationalPointId { - operational_point: "op".into(), + let location = PathItemLocation::OperationalPointReference { + reference: OperationalPointId { + operational_point: "op".into(), + }, + track: None, + track_label: None, }; let path_item = PathItem { id: "a".into(), @@ -235,8 +240,12 @@ mod tests { /// Test deserialize an invalid train schedule #[test] fn deserialize_duplicate_schedule_points_train_schedule() { - let location = PathItemLocation::OperationalPointId { - operational_point: "op".into(), + let location = PathItemLocation::OperationalPointReference { + reference: OperationalPointId { + operational_point: "op".into(), + }, + track: None, + track_label: None, }; let path_item = PathItem { id: "a".into(), @@ -270,8 +279,12 @@ mod tests { /// Test deserialize an invalid train schedule #[test] fn deserialize_arrival_time_first_waypoint_schedule_train_schedule() { - let location = PathItemLocation::OperationalPointId { - operational_point: "op".into(), + let location = PathItemLocation::OperationalPointReference { + reference: OperationalPointId { + operational_point: "op".into(), + }, + track: None, + track_label: None, }; let path_item = PathItem { id: "a".into(), diff --git a/editoast/src/views/path/path_item_cache.rs b/editoast/src/views/path/path_item_cache.rs index 59b63c9514c..16342a2ced3 100644 --- a/editoast/src/views/path/path_item_cache.rs +++ b/editoast/src/views/path/path_item_cache.rs @@ -8,6 +8,7 @@ use std::collections::HashMap; use std::collections::HashSet; use editoast_models::DbConnection; +use editoast_schemas::train_schedule::OperationalPointIdentifier; use editoast_schemas::train_schedule::PathItemLocation; use crate::models::OperationalPointModel; @@ -97,21 +98,26 @@ impl PathItemCache { PathItemLocation::TrackOffset(track_offset) => { vec![track_offset.clone()] } - PathItemLocation::OperationalPointId { operational_point } => { - match self.get_from_id(&operational_point.0) { - Some(op) => op.track_offset(), - None => { - invalid_path_items.push(InvalidPathItem { - index, - path_item: path_item.clone(), - }); - continue; - } + PathItemLocation::OperationalPointReference { + reference: OperationalPointIdentifier::OperationalPointId { operational_point }, + .. + } => match self.get_from_id(&operational_point.0) { + Some(op) => op.track_offset(), + None => { + invalid_path_items.push(InvalidPathItem { + index, + path_item: path_item.clone(), + }); + continue; } - } - PathItemLocation::OperationalPointDescription { - trigram, - secondary_code, + }, + PathItemLocation::OperationalPointReference { + reference: + OperationalPointIdentifier::OperationalPointDescription { + trigram, + secondary_code, + }, + .. } => { let ops = self .get_from_trigram(&trigram.0) @@ -127,9 +133,13 @@ impl PathItemCache { } track_offsets_from_ops(&ops) } - PathItemLocation::OperationalPointUic { - uic, - secondary_code, + PathItemLocation::OperationalPointReference { + reference: + OperationalPointIdentifier::OperationalPointUic { + uic, + secondary_code, + }, + .. } => { let ops = self .get_from_uic(i64::from(*uic)) @@ -183,14 +193,24 @@ fn collect_path_item_ids(path_items: &[&PathItemLocation]) -> (Vec, Vec< for item in path_items { match item { - PathItemLocation::OperationalPointDescription { trigram, .. } => { + PathItemLocation::OperationalPointReference { + reference: OperationalPointIdentifier::OperationalPointDescription { trigram, .. }, + .. + } => { trigrams.push(trigram.clone().0); } - PathItemLocation::OperationalPointUic { uic, .. } => { + PathItemLocation::OperationalPointReference { + reference: OperationalPointIdentifier::OperationalPointUic { uic, .. }, + .. + } => { ops_uic.push(i64::from(*uic)); } - PathItemLocation::OperationalPointId { - operational_point, .. + PathItemLocation::OperationalPointReference { + reference: + OperationalPointIdentifier::OperationalPointId { + operational_point, .. + }, + .. } => { ops_id.push(operational_point.clone().0); } diff --git a/editoast/src/views/path/pathfinding.rs b/editoast/src/views/path/pathfinding.rs index ff892b9a171..45ff809e956 100644 --- a/editoast/src/views/path/pathfinding.rs +++ b/editoast/src/views/path/pathfinding.rs @@ -431,6 +431,7 @@ fn path_input_hash(infra: i64, infra_version: &String, path_input: &PathfindingI pub mod tests { use axum::http::StatusCode; use editoast_models::DbConnectionPoolV2; + use editoast_schemas::train_schedule::OperationalPointIdentifier; use editoast_schemas::train_schedule::PathItemLocation; use pretty_assertions::assert_eq; use rstest::rstest; @@ -475,9 +476,13 @@ pub mod tests { PathfindingInputError::InvalidPathItems { items: vec![InvalidPathItem { index: 1, - path_item: PathItemLocation::OperationalPointDescription { - trigram: "NO_TRIGRAM".into(), - secondary_code: None + path_item: PathItemLocation::OperationalPointReference { + reference: OperationalPointIdentifier::OperationalPointDescription { + trigram: "NO_TRIGRAM".into(), + secondary_code: None + }, + track: None, + track_label: None } }] }