quil_rs/program/
calibration_set.rs1use crate::instruction::CalibrationSignature;
2
3#[derive(Clone, Debug, PartialEq)]
14pub struct CalibrationSet<T> {
15 data: Vec<T>,
19}
20
21impl<T> Default for CalibrationSet<T>
22where
23 T: CalibrationSignature,
24{
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl<T> IntoIterator for CalibrationSet<T> {
31 type IntoIter = std::vec::IntoIter<Self::Item>;
32 type Item = T;
33
34 fn into_iter(self) -> Self::IntoIter {
35 self.data.into_iter()
36 }
37}
38
39impl<T> From<Vec<T>> for CalibrationSet<T>
40where
41 T: CalibrationSignature,
42{
43 fn from(data: Vec<T>) -> Self {
44 let mut set = Self::with_capacity(data.len());
45 for element in data {
46 set.replace(element);
47 }
48 set
49 }
50}
51
52impl<T> CalibrationSet<T>
53where
54 T: CalibrationSignature,
55{
56 pub fn new() -> Self {
58 Self { data: Vec::new() }
59 }
60
61 pub fn with_capacity(capacity: usize) -> Self {
63 Self {
64 data: Vec::with_capacity(capacity),
65 }
66 }
67
68 pub fn capacity(&self) -> usize {
70 self.data.capacity()
71 }
72
73 pub fn len(&self) -> usize {
75 self.data.len()
76 }
77
78 pub fn is_empty(&self) -> bool {
80 self.len() == 0
81 }
82
83 pub fn iter(&self) -> std::slice::Iter<'_, T> {
85 self.data.iter()
86 }
87
88 pub fn get(&self, signature: &<T as CalibrationSignature>::Signature<'_>) -> Option<&T> {
90 if let Some(index) = self.signature_position(signature) {
91 Some(&self.data[index])
92 } else {
93 None
94 }
95 }
96
97 pub fn replace(&mut self, value: T) -> Option<T> {
100 let position = self.signature_position(&value.signature());
101 if let Some(index) = position {
102 let replaced = std::mem::replace(&mut self.data[index], value);
103 Some(replaced)
104 } else {
105 self.data.push(value);
106 None
107 }
108 }
109
110 pub fn remove(&mut self, signature: &<T as CalibrationSignature>::Signature<'_>) -> bool {
112 if let Some(index) = self.signature_position(signature) {
113 self.data.remove(index);
114 true
115 } else {
116 false
117 }
118 }
119
120 fn signature_position(
122 &self,
123 signature: &<T as CalibrationSignature>::Signature<'_>,
124 ) -> Option<usize> {
125 for (i, element) in self.data.iter().enumerate() {
126 if element.has_signature(signature) {
127 return Some(i);
128 }
129 }
130
131 None
132 }
136}
137
138impl<T> Extend<T> for CalibrationSet<T>
139where
140 T: CalibrationSignature,
141{
142 fn extend<I>(&mut self, iter: I)
143 where
144 I: IntoIterator<Item = T>,
145 {
146 for value in iter {
147 self.replace(value);
148 }
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use crate::instruction::CalibrationSignature;
156
157 #[derive(Clone, Debug, PartialEq)]
158 struct TestCalibration {
159 signature: String,
160 data: Option<u8>,
163 }
164
165 impl TestCalibration {
166 fn new(signature: &str, data: Option<u8>) -> Self {
167 Self {
168 signature: signature.to_string(),
169 data,
170 }
171 }
172 }
173
174 impl CalibrationSignature for TestCalibration {
175 type Signature<'a> = &'a str;
176
177 fn signature(&self) -> Self::Signature<'_> {
178 self.signature.as_str()
179 }
180
181 fn has_signature(&self, signature: &Self::Signature<'_>) -> bool {
182 self.signature == *signature
183 }
184 }
185
186 #[test]
187 fn test_replace() {
188 let mut set = CalibrationSet::new();
189 let calib = TestCalibration::new("Signature", None);
190 set.replace(calib.clone());
191 assert_eq!(set.len(), 1);
192 assert!(set.iter().all(|item| item == &calib));
193
194 let calib2 = TestCalibration::new("Signature", Some(42));
195 let replaced = set
196 .replace(calib2.clone())
197 .expect("The original calibration should have been replaced.");
198 assert_eq!(replaced, calib);
199 assert_eq!(set.len(), 1);
200 assert!(set.iter().all(|item| item == &calib2));
201 }
202
203 #[test]
204 fn test_remove_signature() {
205 let mut set = CalibrationSet::new();
206 let calib = TestCalibration::new("Original", None);
207 set.replace(calib.clone());
208 assert!(set.remove(&calib.signature()));
209 assert!(set.is_empty());
210 }
211
212 #[test]
213 fn test_order_sensitive_equality() {
214 let mut set1 = CalibrationSet::new();
215 let mut set2 = CalibrationSet::new();
216 let calib1 = TestCalibration::new("1", None);
217 let calib2 = TestCalibration::new("2", None);
218 set1.extend(vec![calib1.clone(), calib2.clone()]);
219 set2.extend(vec![calib2, calib1]); assert_ne!(set1, set2)
221 }
222
223 #[test]
224 fn test_maintains_insert_order() {
225 let calibs = vec![
226 TestCalibration::new("1", None),
227 TestCalibration::new("2", None),
228 TestCalibration::new("3", None),
229 ];
230 let set = CalibrationSet::from(calibs.clone());
231 let calibs_from_set: Vec<TestCalibration> = set.into_iter().collect();
232 assert_eq!(calibs_from_set, calibs);
233 }
234
235 #[test]
236 fn test_with_capacity() {
237 let capacity = 10;
238 let set: CalibrationSet<TestCalibration> = CalibrationSet::with_capacity(capacity);
239 assert_eq!(set.capacity(), capacity);
240 }
241}