Skip to content

Commit a4ea449

Browse files
committed
editoast: refacto path item location to add track and label information
Signed-off-by: Youness CHRIFI ALAOUI <youness.chrifi@gmail.com>
1 parent 57c96f7 commit a4ea449

File tree

8 files changed

+156
-75
lines changed

8 files changed

+156
-75
lines changed

editoast/editoast_schemas/src/train_schedule.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ pub use schedule_item::ReceptionSignal;
77
pub use schedule_item::ScheduleItem;
88

99
mod path_item;
10+
pub use path_item::OperationalPointIdentifier;
1011
pub use path_item::PathItem;
1112
pub use path_item::PathItemLocation;
13+
pub use path_item::OperationalPointReference;
1214

1315
mod train_schedule_options;
1416
pub use train_schedule_options::TrainScheduleOptions;

editoast/editoast_schemas/src/train_schedule/path_item.rs

+19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::infra::TrackOffset;
99
editoast_common::schemas! {
1010
PathItem,
1111
PathItemLocation,
12+
OperationalPointReference,
1213
}
1314

1415
/// A location on the path of a train
@@ -32,6 +33,24 @@ pub struct PathItem {
3233
#[serde(untagged, deny_unknown_fields)]
3334
pub enum PathItemLocation {
3435
TrackOffset(#[schema(inline)] TrackOffset),
36+
OperationalPointReference(#[schema(inline)] OperationalPointReference),
37+
}
38+
39+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema, Hash)]
40+
pub struct OperationalPointReference {
41+
#[serde(flatten)]
42+
#[schema(inline)]
43+
pub reference: OperationalPointIdentifier,
44+
#[schema(inline)]
45+
#[serde(default)]
46+
pub track_id: Option<Identifier>,
47+
#[serde(default)]
48+
pub track_label: Option<String>,
49+
}
50+
51+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema, Hash)]
52+
#[serde(untagged, deny_unknown_fields)]
53+
pub enum OperationalPointIdentifier {
3554
OperationalPointId {
3655
/// The object id of an operational point
3756
#[schema(inline)]

editoast/editoast_schemas/src/train_schedule/train_schedule_base.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ mod tests {
162162
use serde_json::from_str;
163163
use serde_json::to_string;
164164

165+
use crate::train_schedule::path_item::OperationalPointReference;
166+
use crate::train_schedule::path_item::OperationalPointIdentifier::OperationalPointId;
165167
use crate::train_schedule::schedule_item::ReceptionSignal;
166168
use crate::train_schedule::Margins;
167169
use crate::train_schedule::PathItemLocation;
@@ -180,9 +182,13 @@ mod tests {
180182
/// Test deserialize an invalid train schedule
181183
#[test]
182184
fn deserialize_duplicate_path_id_train_schedule() {
183-
let location = PathItemLocation::OperationalPointId {
184-
operational_point: "op".into(),
185-
};
185+
let location = PathItemLocation::OperationalPointReference(OperationalPointReference{
186+
reference: OperationalPointId {
187+
operational_point: "op".into(),
188+
},
189+
track_id: None,
190+
track_label: None,
191+
});
186192
let path_item = PathItem {
187193
id: "a".into(),
188194
location,
@@ -235,9 +241,13 @@ mod tests {
235241
/// Test deserialize an invalid train schedule
236242
#[test]
237243
fn deserialize_duplicate_schedule_points_train_schedule() {
238-
let location = PathItemLocation::OperationalPointId {
239-
operational_point: "op".into(),
240-
};
244+
let location = PathItemLocation::OperationalPointReference(OperationalPointReference {
245+
reference: OperationalPointId {
246+
operational_point: "op".into(),
247+
},
248+
track_id: None,
249+
track_label: None,
250+
});
241251
let path_item = PathItem {
242252
id: "a".into(),
243253
location,
@@ -270,9 +280,13 @@ mod tests {
270280
/// Test deserialize an invalid train schedule
271281
#[test]
272282
fn deserialize_arrival_time_first_waypoint_schedule_train_schedule() {
273-
let location = PathItemLocation::OperationalPointId {
274-
operational_point: "op".into(),
275-
};
283+
let location = PathItemLocation::OperationalPointReference(OperationalPointReference{
284+
reference: OperationalPointId {
285+
operational_point: "op".into(),
286+
},
287+
track_id: None,
288+
track_label: None,
289+
});
276290
let path_item = PathItem {
277291
id: "a".into(),
278292
location,

editoast/openapi.yaml

+47-32
Original file line numberDiff line numberDiff line change
@@ -7073,6 +7073,52 @@ components:
70737073
maxLength: 255
70747074
minLength: 1
70757075
additionalProperties: false
7076+
OperationalPointReference:
7077+
allOf:
7078+
- oneOf:
7079+
- type: object
7080+
required:
7081+
- operational_point
7082+
properties:
7083+
operational_point:
7084+
type: string
7085+
maxLength: 255
7086+
minLength: 1
7087+
- type: object
7088+
required:
7089+
- trigram
7090+
properties:
7091+
secondary_code:
7092+
type: string
7093+
description: An optional secondary code to identify a more specific location
7094+
nullable: true
7095+
trigram:
7096+
type: string
7097+
minLength: 1
7098+
- type: object
7099+
required:
7100+
- uic
7101+
properties:
7102+
secondary_code:
7103+
type: string
7104+
description: An optional secondary code to identify a more specific location
7105+
nullable: true
7106+
uic:
7107+
type: integer
7108+
format: int32
7109+
description: The [UIC](https://en.wikipedia.org/wiki/List_of_UIC_country_codes) code of an operational point
7110+
minimum: 0
7111+
- type: object
7112+
properties:
7113+
track_id:
7114+
allOf:
7115+
- type: string
7116+
maxLength: 255
7117+
minLength: 1
7118+
nullable: true
7119+
track_label:
7120+
type: string
7121+
nullable: true
70767122
Ordering:
70777123
type: string
70787124
enum:
@@ -7234,38 +7280,7 @@ components:
72347280
PathItemLocation:
72357281
oneOf:
72367282
- $ref: '#/components/schemas/TrackOffset'
7237-
- type: object
7238-
required:
7239-
- operational_point
7240-
properties:
7241-
operational_point:
7242-
type: string
7243-
maxLength: 255
7244-
minLength: 1
7245-
- type: object
7246-
required:
7247-
- trigram
7248-
properties:
7249-
secondary_code:
7250-
type: string
7251-
description: An optional secondary code to identify a more specific location
7252-
nullable: true
7253-
trigram:
7254-
type: string
7255-
minLength: 1
7256-
- type: object
7257-
required:
7258-
- uic
7259-
properties:
7260-
secondary_code:
7261-
type: string
7262-
description: An optional secondary code to identify a more specific location
7263-
nullable: true
7264-
uic:
7265-
type: integer
7266-
format: int32
7267-
description: The [UIC](https://en.wikipedia.org/wiki/List_of_UIC_country_codes) code of an operational point
7268-
minimum: 0
7283+
- $ref: '#/components/schemas/OperationalPointReference'
72697284
description: The location of a path waypoint
72707285
PathProperties:
72717286
type: object

editoast/src/views/path/path_item_cache.rs

+46-24
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ use crate::error::Result;
44
use crate::models::TrackSectionModel;
55
use crate::RetrieveBatchUnchecked;
66
use editoast_schemas::infra::TrackOffset;
7+
use editoast_schemas::train_schedule::OperationalPointReference;
78
use std::collections::HashMap;
89
use std::collections::HashSet;
910

1011
use editoast_models::DbConnection;
12+
use editoast_schemas::train_schedule::OperationalPointIdentifier;
1113
use editoast_schemas::train_schedule::PathItemLocation;
1214

1315
use crate::models::OperationalPointModel;
@@ -93,26 +95,32 @@ impl PathItemCache {
9395
let mut result: Vec<Vec<_>> = Vec::default();
9496
let mut invalid_path_items = Vec::new();
9597
for (index, &path_item) in path_items.iter().enumerate() {
98+
dbg!(&path_item);
9699
let track_offsets = match path_item {
97100
PathItemLocation::TrackOffset(track_offset) => {
98101
vec![track_offset.clone()]
99102
}
100-
PathItemLocation::OperationalPointId { operational_point } => {
101-
match self.get_from_id(&operational_point.0) {
102-
Some(op) => op.track_offset(),
103-
None => {
104-
invalid_path_items.push(InvalidPathItem {
105-
index,
106-
path_item: path_item.clone(),
107-
});
108-
continue;
109-
}
103+
PathItemLocation::OperationalPointReference(OperationalPointReference{
104+
reference: OperationalPointIdentifier::OperationalPointId { operational_point },
105+
..
106+
}) => match self.get_from_id(&operational_point.0) {
107+
Some(op) => op.track_offset(),
108+
None => {
109+
invalid_path_items.push(InvalidPathItem {
110+
index,
111+
path_item: path_item.clone(),
112+
});
113+
continue;
110114
}
111-
}
112-
PathItemLocation::OperationalPointDescription {
113-
trigram,
114-
secondary_code,
115-
} => {
115+
},
116+
PathItemLocation::OperationalPointReference(OperationalPointReference {
117+
reference:
118+
OperationalPointIdentifier::OperationalPointDescription {
119+
trigram,
120+
secondary_code,
121+
},
122+
..
123+
}) => {
116124
let ops = self
117125
.get_from_trigram(&trigram.0)
118126
.cloned()
@@ -127,10 +135,14 @@ impl PathItemCache {
127135
}
128136
track_offsets_from_ops(&ops)
129137
}
130-
PathItemLocation::OperationalPointUic {
131-
uic,
132-
secondary_code,
133-
} => {
138+
PathItemLocation::OperationalPointReference(OperationalPointReference{
139+
reference:
140+
OperationalPointIdentifier::OperationalPointUic {
141+
uic,
142+
secondary_code,
143+
},
144+
..
145+
}) => {
134146
let ops = self
135147
.get_from_uic(i64::from(*uic))
136148
.cloned()
@@ -183,15 +195,25 @@ fn collect_path_item_ids(path_items: &[&PathItemLocation]) -> (Vec<String>, Vec<
183195

184196
for item in path_items {
185197
match item {
186-
PathItemLocation::OperationalPointDescription { trigram, .. } => {
198+
PathItemLocation::OperationalPointReference(OperationalPointReference{
199+
reference: OperationalPointIdentifier::OperationalPointDescription { trigram, .. },
200+
..
201+
} )=> {
187202
trigrams.push(trigram.clone().0);
188203
}
189-
PathItemLocation::OperationalPointUic { uic, .. } => {
204+
PathItemLocation::OperationalPointReference(OperationalPointReference{
205+
reference: OperationalPointIdentifier::OperationalPointUic { uic, .. },
206+
..
207+
}) => {
190208
ops_uic.push(i64::from(*uic));
191209
}
192-
PathItemLocation::OperationalPointId {
193-
operational_point, ..
194-
} => {
210+
PathItemLocation::OperationalPointReference(OperationalPointReference {
211+
reference:
212+
OperationalPointIdentifier::OperationalPointId {
213+
operational_point, ..
214+
},
215+
..
216+
}) => {
195217
ops_id.push(operational_point.clone().0);
196218
}
197219
_ => {}

editoast/src/views/path/pathfinding.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ fn path_input_hash(infra: i64, infra_version: &String, path_input: &PathfindingI
431431
pub mod tests {
432432
use axum::http::StatusCode;
433433
use editoast_models::DbConnectionPoolV2;
434+
use editoast_schemas::train_schedule::OperationalPointReference;
435+
use editoast_schemas::train_schedule::OperationalPointIdentifier;
434436
use editoast_schemas::train_schedule::PathItemLocation;
435437
use pretty_assertions::assert_eq;
436438
use rstest::rstest;
@@ -457,7 +459,7 @@ pub mod tests {
457459
"path_items":[
458460
{"trigram":"WS","secondary_code":"BV"},
459461
{"trigram":"NO_TRIGRAM","secondary_code":null},
460-
{"trigram":"SWS","secondary_code":"BV"}
462+
{"trigram":"SWS","secondary_code":"BV",}
461463
],
462464
"rolling_stock_is_thermal":true,
463465
"rolling_stock_loading_gauge":"G1",
@@ -475,10 +477,14 @@ pub mod tests {
475477
PathfindingInputError::InvalidPathItems {
476478
items: vec![InvalidPathItem {
477479
index: 1,
478-
path_item: PathItemLocation::OperationalPointDescription {
479-
trigram: "NO_TRIGRAM".into(),
480-
secondary_code: None
481-
}
480+
path_item: PathItemLocation::OperationalPointReference(OperationalPointReference {
481+
reference: OperationalPointIdentifier::OperationalPointDescription {
482+
trigram: "NO_TRIGRAM".into(),
483+
secondary_code: None
484+
},
485+
track: None,
486+
track_label: None
487+
})
482488
}]
483489
}
484490
))

editoast/src/views/timetable.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,12 @@ async fn train_schedule(
229229
}
230230

231231
let conn = &mut db_pool.get().await?;
232-
232+
233233
let timetable_id = timetable_id.id;
234234
TimetableWithTrains::retrieve_or_fail(conn, timetable_id, || TimetableError::NotFound {
235235
timetable_id,
236236
})
237237
.await?;
238-
239238
let changesets: Vec<TrainScheduleChangeset> = train_schedules
240239
.into_iter()
241240
.map(|ts| TrainScheduleForm {

front/src/common/api/generatedEditoastApi.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -2421,8 +2421,7 @@ export type TrackOffset = {
24212421
offset: number;
24222422
track: string;
24232423
};
2424-
export type PathItemLocation =
2425-
| TrackOffset
2424+
export type OperationalPointReference = (
24262425
| {
24272426
operational_point: string;
24282427
}
@@ -2436,7 +2435,12 @@ export type PathItemLocation =
24362435
secondary_code?: string | null;
24372436
/** The [UIC](https://en.wikipedia.org/wiki/List_of_UIC_country_codes) code of an operational point */
24382437
uic: number;
2439-
};
2438+
}
2439+
) & {
2440+
track_id?: string | null;
2441+
track_label?: string | null;
2442+
};
2443+
export type PathItemLocation = TrackOffset | OperationalPointReference;
24402444
export type PathfindingInputError =
24412445
| {
24422446
error_type: 'invalid_path_items';

0 commit comments

Comments
 (0)