message: Implement measurement taking
diff: @@ -5,7 +5,7 @@ use crate::code_blocks::BlockId;
  #[derive(Default, Debug)]
  pub struct Measurements {
  - data: Vec<Measurement>,
  + pub data: Vec<Measurement>,
  }
  impl Measurements {
  @@ -14,11 +14,18 @@ impl Measurements {
  }
  pub fn start_measurement(&mut self) -> MeasurementId {
  - todo!()
  + self.data.push(Measurement::Started(time::Instant::now()));
  + MeasurementId(self.data.len() - 1)
  }
  - pub fn take_measurement(&mut self, id: impl Into<MeasurementId>, block: BlockId) {
  - todo!()
  + // TODO: Error handling? This will be called from Wasm code probably.
  + pub fn take_measurement(&mut self, id: impl Into<MeasurementId>, block: impl Into<BlockId>) {
  + let id = id.into().0;
  +
  + // We're not sure if this id exists.
  + if let Measurement::Started(start) = self.data[id] {
  + self.data[id] = Measurement::Taken(start.elapsed(), block.into());
  + }
  }
  }
  @@ -28,22 +35,60 @@ pub enum Measurement {
  Taken(time::Duration, BlockId),
  }
  -pub struct MeasurementId(u32);
  +pub struct MeasurementId(usize);
  -impl From<u32> for MeasurementId {
  - fn from(hash: u32) -> Self {
  - Self(hash)
  +impl From<usize> for MeasurementId {
  + fn from(num: usize) -> Self {
  + Self(num)
  }
  }
  -impl PartialEq<u32> for MeasurementId {
  - fn eq(&self, rhs: &u32) -> bool {
  +impl PartialEq<usize> for MeasurementId {
  + fn eq(&self, rhs: &usize) -> bool {
  self.0 == *rhs
  }
  }
  -impl PartialEq<MeasurementId> for u32 {
  +impl PartialEq<MeasurementId> for usize {
  fn eq(&self, rhs: &MeasurementId) -> bool {
  rhs.0 == *self
  }
  }
  +
  +#[cfg(test)]
  +mod tests {
  + use super::*;
  +
  + #[test]
  + fn take_measurements() {
  + let mut measure = Measurements::new();
  +
  + let m_id1 = measure.start_measurement();
  + let _m_id2 = measure.start_measurement();
  + std::thread::sleep(time::Duration::from_millis(100));
  + let m_id3 = measure.start_measurement();
  +
  + measure.take_measurement(m_id1, 0);
  + measure.take_measurement(m_id3, 0);
  +
  + assert_eq!(measure.data.len(), 3);
  +
  + let mut measures = measure.data.iter();
  +
  + match measures.next().unwrap() {
  + Measurement::Taken(duration, block) => {
  + assert!(*duration > time::Duration::from_millis(100));
  + }
  + _ => panic!("failed to take measurement"),
  + }
  + if let Measurement::Taken(..) = measures.next().unwrap() {
  + panic!("second measurement should be unfinished");
  + }
  + match measures.next().unwrap() {
  + Measurement::Taken(duration, block) => {
  + assert!(*duration < time::Duration::from_millis(25));
  + }
  + _ => panic!("failed to take measurement"),
  + }
  + }
  +}
  