From dc827c682608903718ec799235c19467ff058720 Mon Sep 17 00:00:00 2001 From: Jean SIMARD Date: Tue, 17 Sep 2024 15:06:18 +0200 Subject: [PATCH] editoast: make intersection as a type Signed-off-by: Jean SIMARD --- editoast/openapi.yaml | 27 ++++++---- editoast/src/views/path.rs | 1 + editoast/src/views/path/projection.rs | 53 ++++++++++++++++--- .../src/views/train_schedule/projection.rs | 3 +- editoast/src/views/work_schedules.rs | 8 ++- front/src/common/api/generatedEditoastApi.ts | 8 ++- 6 files changed, 79 insertions(+), 21 deletions(-) diff --git a/editoast/openapi.yaml b/editoast/openapi.yaml index 991796f7bd6..26283f60e69 100644 --- a/editoast/openapi.yaml +++ b/editoast/openapi.yaml @@ -2792,15 +2792,7 @@ paths: path_position_ranges: type: array items: - type: array - items: - allOf: - - type: integer - format: int64 - minimum: 0 - - type: integer - format: int64 - minimum: 0 + $ref: '#/components/schemas/Intersection' description: |- a list of intervals `(a, b)` that represent the projections of the work schedule track ranges: - `a` is the distance from the beginning of the path to the beginning of the track range @@ -6039,6 +6031,23 @@ components: minimum: 100 type: type: string + Intersection: + type: object + description: Represent the intersection between a track range and a path, relative to the beginning of the path + required: + - start + - end + properties: + end: + type: integer + format: int64 + description: Distance of the end of the intersection relative to the beginning of the path + minimum: 0 + start: + type: integer + format: int64 + description: Distance of the beginning of the intersection relative to the beginning of the path + minimum: 0 LevelValues: type: array items: diff --git a/editoast/src/views/path.rs b/editoast/src/views/path.rs index 11dbee0e06a..c47c512ed4f 100644 --- a/editoast/src/views/path.rs +++ b/editoast/src/views/path.rs @@ -21,6 +21,7 @@ crate::routes! { editoast_common::schemas! { pathfinding::schemas(), + projection::schemas(), properties::schemas(), TrackRange, } diff --git a/editoast/src/views/path/projection.rs b/editoast/src/views/path/projection.rs index 1ddcce447d4..2a50e79d779 100644 --- a/editoast/src/views/path/projection.rs +++ b/editoast/src/views/path/projection.rs @@ -5,6 +5,10 @@ use std::collections::HashMap; use super::TrackRange; +editoast_common::schemas! { + Intersection, +} + /// This object is useful to: /// - Get the position in the path given a location (track section and offset). /// - Get the location (track section and offset) given a position in a path. @@ -134,7 +138,7 @@ impl<'a> PathProjection<'a> { /// If there is no common track section range, the returned list is empty. /// The positions in the intersection list are guaranteed to increase. In other words `list[n].0 < list[n].1 <= list[n+1].0 < list[n+1].1` /// These positions can then be use in conjunction with [PathProjection::get_location]. - pub fn get_intersections(&self, track_ranges: &[TrackRange]) -> Vec<(u64, u64)> { + pub fn get_intersections(&self, track_ranges: &[TrackRange]) -> Vec { // Handle the length computation in mm let mut next_pos: u64 = 0; let mut current_pos: u64; @@ -206,10 +210,35 @@ impl<'a> PathProjection<'a> { } } +/// Represent the intersection between a track range and a path, relative to the beginning of the path +#[derive(Debug, serde::Serialize, serde::Deserialize, PartialEq, utoipa::ToSchema)] +pub struct Intersection { + /// Distance of the beginning of the intersection relative to the beginning of the path + start: u64, + /// Distance of the end of the intersection relative to the beginning of the path + end: u64, +} +impl From<(u64, u64)> for Intersection { + fn from((start, end): (u64, u64)) -> Self { + debug_assert!( + start <= end, + "intersection should have a 'start' ({start}) smaller than 'end' ({end})" + ); + Self { start, end } + } +} +impl Intersection { + pub fn start(&self) -> u64 { + self.start + } + pub fn end(&self) -> u64 { + self.end + } +} struct IntersectionBuilder { start: Option, current: u64, - intersections: Vec<(u64, u64)>, + intersections: Vec, } impl IntersectionBuilder { @@ -224,7 +253,8 @@ impl IntersectionBuilder { fn finish(&mut self) { if let Some(start) = self.start { assert_ne!(start, self.current); - self.intersections.push((start, self.current)); + self.intersections + .push(Intersection::from((start, self.current))); } self.start = None; } @@ -396,7 +426,7 @@ mod tests { ]; let boundaries = projection.get_intersections(&track_ranges); - let expected: Vec<(u64, u64)> = vec![(50, 730)]; + let expected: Vec = vec![Intersection::from((50, 730))]; assert_eq!(boundaries, expected); } @@ -421,7 +451,10 @@ mod tests { ]; let boundaries = projection.get_intersections(&track_ranges); - let expected: Vec<(u64, u64)> = vec![(100, 350), (350, 420)]; + let expected: Vec = vec![ + Intersection::from((100, 350)), + Intersection::from((350, 420)), + ]; assert_eq!(boundaries, expected); } @@ -447,7 +480,11 @@ mod tests { ]; let boundaries = projection.get_intersections(&track_ranges); - let expected: Vec<(u64, u64)> = vec![(50, 300), (400, 450), (550, 620)]; + let expected: Vec = vec![ + Intersection::from((50, 300)), + Intersection::from((400, 450)), + Intersection::from((550, 620)), + ]; assert_eq!(boundaries, expected); } @@ -461,7 +498,7 @@ mod tests { let boundaries = projection.get_intersections(&track_ranges); - let expected: Vec<(u64, u64)> = vec![]; + let expected: Vec = vec![]; assert_eq!(boundaries, expected); } @@ -474,7 +511,7 @@ mod tests { let boundaries = projection.get_intersections(&track_ranges); - let expected: Vec<(u64, u64)> = vec![]; + let expected: Vec = vec![]; assert_eq!(boundaries, expected); } } diff --git a/editoast/src/views/train_schedule/projection.rs b/editoast/src/views/train_schedule/projection.rs index fb7e1405a5f..4fbcc8c5222 100644 --- a/editoast/src/views/train_schedule/projection.rs +++ b/editoast/src/views/train_schedule/projection.rs @@ -399,7 +399,8 @@ fn compute_space_time_curves( let mut space_time_curves = vec![]; for intersection in intersections { - let (start, end) = intersection; + let start = intersection.start(); + let end = intersection.end(); let start_index = find_index_upper(positions, start); let end_index = find_index_upper(positions, end); diff --git a/editoast/src/views/work_schedules.rs b/editoast/src/views/work_schedules.rs index e8917ca9765..6a481dd779f 100644 --- a/editoast/src/views/work_schedules.rs +++ b/editoast/src/views/work_schedules.rs @@ -21,6 +21,7 @@ use crate::models::prelude::*; use crate::models::work_schedules::WorkSchedule; use crate::models::work_schedules::WorkScheduleGroup; use crate::models::work_schedules::WorkScheduleType; +use crate::views::path::projection::Intersection; use crate::views::path::projection::PathProjection; use crate::views::AuthorizationError; use crate::views::AuthorizerExt; @@ -202,7 +203,7 @@ struct WorkScheduleProjection { /// a list of intervals `(a, b)` that represent the projections of the work schedule track ranges: /// - `a` is the distance from the beginning of the path to the beginning of the track range /// - `b` is the distance from the beginning of the path to the end of the track range - pub path_position_ranges: Vec<(u64, u64)>, + pub path_position_ranges: Vec, } #[utoipa::path( @@ -498,7 +499,10 @@ pub mod test { work_schedule_type: work_schedules[index].work_schedule_type, start_date_time: work_schedules[index].start_date_time, end_date_time: work_schedules[index].end_date_time, - path_position_ranges: position_ranges, + path_position_ranges: position_ranges + .into_iter() + .map(Intersection::from) + .collect(), }) .collect(); diff --git a/front/src/common/api/generatedEditoastApi.ts b/front/src/common/api/generatedEditoastApi.ts index 3221987bb80..a03acee4ba8 100644 --- a/front/src/common/api/generatedEditoastApi.ts +++ b/front/src/common/api/generatedEditoastApi.ts @@ -1497,7 +1497,7 @@ export type PostWorkSchedulesProjectPathApiResponse = /** a list of intervals `(a, b)` that represent the projections of the work schedule track ranges: - `a` is the distance from the beginning of the path to the beginning of the track range - `b` is the distance from the beginning of the path to the end of the track range */ - path_position_ranges: (number & number)[][]; + path_position_ranges: Intersection[]; /** The date and time when the work schedule takes effect. */ start_date_time: string; type: 'CATENARY' | 'TRACK'; @@ -3067,3 +3067,9 @@ export type WorkScheduleCreateForm = { work_schedule_group_name: string; work_schedules: WorkScheduleItemForm[]; }; +export type Intersection = { + /** Distance of the end of the intersection relative to the beginning of the path */ + end: number; + /** Distance of the beginning of the intersection relative to the beginning of the path */ + start: number; +};