-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathutils.rs
113 lines (105 loc) · 4.39 KB
/
utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::collections::HashSet;
use crate::infra_cache::operation::CacheOperation;
use crate::infra_cache::InfraCache;
use crate::infra_cache::ObjectCache;
use editoast_schemas::primitives::OSRDIdentified;
use editoast_schemas::primitives::OSRDObject;
use editoast_schemas::primitives::ObjectType;
/// This struct gives a set of objects that needs to be updated or deleted given a list of operations.
#[derive(Debug, Clone, Default)]
pub struct InvolvedObjects<'a> {
/// Ids of objects that needs to be updated
pub updated: HashSet<&'a String>,
/// Ids of objects that needs to be deleted
pub deleted: HashSet<&'a String>,
}
impl<'a> InvolvedObjects<'a> {
/// Given a list of operations and an object type, return a set of object ids that needs to be updated or deleted.
/// For example if you have an operation that modify a Track Section, and you call this function with `ObjectType::Signal` as `obj_type`,
/// You'll have the set of signal ids that are linked to the track section that has been modified.
pub fn from_operations(
operations: &'a [CacheOperation],
infra_cache: &'a InfraCache,
obj_type: ObjectType,
) -> Self {
let mut res = Self::default();
for op in operations {
match op {
CacheOperation::Create(object_cache) | CacheOperation::Update(object_cache)
if object_cache.get_type() == obj_type =>
{
res.updated.insert(object_cache.get_id());
}
CacheOperation::Create(ObjectCache::TrackSection(track_section))
| CacheOperation::Update(ObjectCache::TrackSection(track_section)) => {
// Retrieve all the objects that are linked to the track section
infra_cache
.get_track_refs_type(track_section.get_id(), obj_type)
.iter()
.for_each(|obj_ref| {
res.updated.insert(&obj_ref.obj_id);
});
}
CacheOperation::Delete(obj_ref) if obj_ref.obj_type == obj_type => {
res.deleted.insert(&obj_ref.obj_id);
}
_ => (),
}
}
res
}
/// Check if there is involved objects. Returns `true` if no objects must be updated or deleted.
pub fn is_empty(&self) -> bool {
self.updated.is_empty() && self.deleted.is_empty()
}
}
#[cfg(test)]
mod tests {
use std::collections::HashSet;
use super::InvolvedObjects;
use crate::infra_cache::object_cache::DetectorCache;
use crate::infra_cache::object_cache::TrackSectionCache;
use crate::infra_cache::operation::CacheOperation;
use crate::infra_cache::tests::create_small_infra_cache;
use crate::infra_cache::ObjectCache;
use editoast_schemas::primitives::ObjectRef;
use editoast_schemas::primitives::ObjectType;
#[test]
fn track_section_deleted() {
let infra_cache = create_small_infra_cache();
let track = String::from("A");
let operations = vec![CacheOperation::Delete(ObjectRef::new(
ObjectType::TrackSection,
&track,
))];
let involved_objects =
InvolvedObjects::from_operations(&operations, &infra_cache, ObjectType::TrackSection);
assert_eq!(involved_objects.updated.len(), 0);
assert_eq!(involved_objects.deleted, HashSet::from([&track]));
}
#[test]
fn detectors_when_track_section_update() {
let infra_cache = create_small_infra_cache();
let track = String::from("B");
let operations = vec![
CacheOperation::Update(ObjectCache::TrackSection(TrackSectionCache {
obj_id: track,
length: 420.,
..Default::default()
})),
CacheOperation::Create(ObjectCache::Detector(DetectorCache {
obj_id: "D2".to_string(),
track: "TA1".to_string(),
position: 42.0,
})),
];
let involved_objects =
InvolvedObjects::from_operations(&operations, &infra_cache, ObjectType::Detector);
assert_eq!(involved_objects.deleted.len(), 0);
let detectors = ["D1".into(), "D2".into()];
assert_eq!(
involved_objects.updated,
detectors.iter().collect::<HashSet<_>>()
);
}
}