@@ -4,7 +4,9 @@ use crate::error::Result;
4
4
use crate :: models:: TrackSectionModel ;
5
5
use crate :: RetrieveBatchUnchecked ;
6
6
use editoast_schemas:: infra:: TrackOffset ;
7
+ use editoast_schemas:: primitives:: NonBlankString ;
7
8
use editoast_schemas:: train_schedule:: OperationalPointReference ;
9
+ use editoast_schemas:: train_schedule:: TrackReference ;
8
10
use std:: collections:: HashMap ;
9
11
use std:: collections:: HashSet ;
10
12
@@ -25,6 +27,7 @@ pub struct PathItemCache {
25
27
trigram_to_ops : HashMap < String , Vec < OperationalPointModel > > ,
26
28
ids_to_ops : HashMap < String , OperationalPointModel > ,
27
29
existing_track_ids : HashSet < String > ,
30
+ existing_track_labels : HashMap < String , NonBlankString > ,
28
31
}
29
32
30
33
impl PathItemCache {
@@ -53,17 +56,30 @@ impl PathItemCache {
53
56
. map ( |part| ( infra_id, part. track . 0 . clone ( ) ) )
54
57
. chain ( tracks) ;
55
58
let existing_track_ids =
56
- TrackSectionModel :: retrieve_batch_unchecked :: < _ , Vec < _ > > ( conn, tracks)
59
+ TrackSectionModel :: retrieve_batch_unchecked :: < _ , Vec < _ > > ( conn, tracks. clone ( ) )
57
60
. await ?
58
61
. into_iter ( )
59
62
. map ( |track| track. obj_id )
60
63
. collect ( ) ;
64
+ let existing_track_labels =
65
+ TrackSectionModel :: retrieve_batch_unchecked :: < _ , Vec < _ > > ( conn, tracks)
66
+ . await ?
67
+ . into_iter ( )
68
+ . filter_map ( |track| {
69
+ track
70
+ . extensions
71
+ . sncf
72
+ . as_ref ( )
73
+ . map ( |extension| ( track. obj_id . clone ( ) , extension. line_name . clone ( ) ) )
74
+ } )
75
+ . collect ( ) ;
61
76
62
77
Ok ( PathItemCache {
63
78
uic_to_ops,
64
79
trigram_to_ops,
65
80
ids_to_ops,
66
81
existing_track_ids,
82
+ existing_track_labels,
67
83
} )
68
84
}
69
85
@@ -95,16 +111,18 @@ impl PathItemCache {
95
111
let mut result: Vec < Vec < _ > > = Vec :: default ( ) ;
96
112
let mut invalid_path_items = Vec :: new ( ) ;
97
113
for ( index, & path_item) in path_items. iter ( ) . enumerate ( ) {
98
- dbg ! ( & path_item) ;
99
114
let track_offsets = match path_item {
100
115
PathItemLocation :: TrackOffset ( track_offset) => {
101
116
vec ! [ track_offset. clone( ) ]
102
117
}
103
118
PathItemLocation :: OperationalPointReference ( OperationalPointReference {
104
119
reference : OperationalPointIdentifier :: OperationalPointId { operational_point } ,
105
- ..
120
+ track_reference ,
106
121
} ) => match self . get_from_id ( & operational_point. 0 ) {
107
- Some ( op) => op. track_offset ( ) ,
122
+ Some ( op) => {
123
+ let track_offsets = op. track_offset ( ) ;
124
+ self . track_reference_filter ( track_offsets, track_reference)
125
+ }
108
126
None => {
109
127
invalid_path_items. push ( InvalidPathItem {
110
128
index,
@@ -119,7 +137,7 @@ impl PathItemCache {
119
137
trigram,
120
138
secondary_code,
121
139
} ,
122
- ..
140
+ track_reference ,
123
141
} ) => {
124
142
let ops = self
125
143
. get_from_trigram ( & trigram. 0 )
@@ -133,15 +151,16 @@ impl PathItemCache {
133
151
} ) ;
134
152
continue ;
135
153
}
136
- track_offsets_from_ops ( & ops)
154
+ let track_offsets = track_offsets_from_ops ( & ops) ;
155
+ self . track_reference_filter ( track_offsets, track_reference)
137
156
}
138
157
PathItemLocation :: OperationalPointReference ( OperationalPointReference {
139
158
reference :
140
159
OperationalPointIdentifier :: OperationalPointUic {
141
160
uic,
142
161
secondary_code,
143
162
} ,
144
- ..
163
+ track_reference ,
145
164
} ) => {
146
165
let ops = self
147
166
. get_from_uic ( i64:: from ( * uic) )
@@ -155,7 +174,8 @@ impl PathItemCache {
155
174
} ) ;
156
175
continue ;
157
176
}
158
- track_offsets_from_ops ( & ops)
177
+ let track_offsets = track_offsets_from_ops ( & ops) ;
178
+ self . track_reference_filter ( track_offsets, track_reference)
159
179
}
160
180
} ;
161
181
@@ -185,6 +205,34 @@ impl PathItemCache {
185
205
186
206
Ok ( result)
187
207
}
208
+
209
+ /// Filter operational points parts by a track label or a track id
210
+ /// If neither a track label or id is provided, the original list is returned
211
+ fn track_reference_filter (
212
+ & self ,
213
+ track_offsets : Vec < TrackOffset > ,
214
+ track_reference : & Option < TrackReference > ,
215
+ ) -> Vec < TrackOffset > {
216
+ if let Some ( track_reference) = track_reference {
217
+ match track_reference {
218
+ TrackReference :: Id { track_id } => track_offsets
219
+ . into_iter ( )
220
+ . filter ( |track_offset| & track_offset. track == track_id)
221
+ . collect ( ) ,
222
+ TrackReference :: Label { track_label } => track_offsets
223
+ . into_iter ( )
224
+ . filter ( |track_offset| {
225
+ self . existing_track_labels
226
+ . get :: < String > ( & track_offset. track )
227
+ . unwrap ( )
228
+ == track_label
229
+ } )
230
+ . collect ( ) ,
231
+ }
232
+ } else {
233
+ track_offsets
234
+ }
235
+ }
188
236
}
189
237
190
238
/// Collect the ids of the operational points from the path items
0 commit comments