Skip to main content

rustdds/dds/with_key/
datasample.rs

1use crate::{
2  dds::{key::*, sampleinfo::*, with_key::datawriter::WriteOptions},
3  structure::{
4    cache_change::CacheChange, guid::GUID, sequence_number::SequenceNumber, time::Timestamp,
5  },
6};
7
8/// A data sample received from a WITH_KEY Topic without the associated
9/// metadata.
10///
11/// Replaces the use of `valid_data` flag in SampleInfo of DataSample from the
12/// DDS spec.
13///
14/// Implements the methods `value`, `map_value`, `map_dispose`, and
15/// `as_ref`. The `unwrap` method is deprecated — use `value()` or match on
16/// `Sample::Value` / `Sample::Dispose` instead.
17#[derive(Clone, PartialEq, Debug)]
18pub enum Sample<D, K> {
19  Value(D),
20  Dispose(K),
21}
22
23impl<D, K> Sample<D, K> {
24  pub fn value(self) -> Option<D> {
25    match self {
26      Sample::Value(d) => Some(d),
27      Sample::Dispose(_) => None,
28    }
29  }
30
31  pub fn map_value<D2, F: FnOnce(D) -> D2>(self, op: F) -> Sample<D2, K> {
32    match self {
33      Sample::Value(d) => Sample::Value(op(d)),
34      Sample::Dispose(k) => Sample::Dispose(k),
35    }
36  }
37
38  pub fn map_dispose<K2, F: FnOnce(K) -> K2>(self, op: F) -> Sample<D, K2> {
39    match self {
40      Sample::Value(d) => Sample::Value(d),
41      Sample::Dispose(k) => Sample::Dispose(op(k)),
42    }
43  }
44
45  #[deprecated(note = "panics on Sample::Dispose; use value() or match on Sample::Value/Dispose")]
46  /// Returns the data sample, panicking if this is a dispose notification.
47  ///
48  /// # Panics
49  ///
50  /// Panics if called on [`Sample::Dispose`]. Use [`Self::value`] or match on
51  /// [`Sample::Value`](Sample::Value) / [`Sample::Dispose`](Sample::Dispose).
52  pub fn unwrap(self) -> D {
53    match self {
54      Sample::Value(d) => d,
55      Sample::Dispose(_k) => panic!(
56        "Unwrap called on a Sample with no data (Dispose notification). Use Sample::value() \
57         instead."
58      ),
59    }
60  }
61
62  pub const fn as_ref(&self) -> Sample<&D, &K> {
63    match *self {
64      Sample::Value(ref d) => Sample::Value(d),
65      Sample::Dispose(ref k) => Sample::Dispose(k),
66    }
67  }
68}
69
70/// A data sample and its associated [metadata](`SampleInfo`) received from a
71/// WITH_KEY Topic.
72///
73/// Note that [`no_key::DataSample`](crate::no_key::DataSample) and
74/// [`with_key::DataSample`](crate::with_key::DataSample) are two different
75/// structs.
76///
77/// We are using [`Sample`](crate::with_key::Sample) to replace the `valid_data`
78/// flag from the DDS spec, because when `valid_data = false`, the application
79/// should not be able to access any data.
80///
81/// Sample usage:
82/// * `Sample::Value(d)` means `valid_data == true` and there is a sample `d`.
83/// * `Sample::Dispose(k)` means `valid_data == false`, no sample exists, but
84///   only a Key `k` and instance_state has changed.
85///
86/// See also DDS spec v1.4 Section 2.2.2.5.4.
87#[derive(PartialEq, Debug)]
88pub struct DataSample<D: Keyed> {
89  pub(crate) sample_info: SampleInfo, // TODO: Can we somehow make this lazily evaluated?
90
91  pub(crate) value: Sample<D, D::K>,
92}
93
94impl<D> DataSample<D>
95where
96  D: Keyed,
97{
98  pub(crate) fn new(sample_info: SampleInfo, value: Sample<D, D::K>) -> Self {
99    Self { sample_info, value }
100  }
101
102  // convenience shorthand to get the key directly, without digging out the
103  // "value"
104  pub fn key(&self) -> D::K {
105    match &self.value {
106      Sample::Value(d) => d.key(),
107      Sample::Dispose(k) => k.clone(),
108    }
109  } // fn
110
111  pub fn value(&self) -> &Sample<D, D::K> {
112    &self.value
113  }
114
115  pub fn into_value(self) -> Sample<D, D::K> {
116    self.value
117  }
118
119  pub fn sample_info(&self) -> &SampleInfo {
120    &self.sample_info
121  }
122
123  pub fn sample_info_mut(&mut self) -> &mut SampleInfo {
124    &mut self.sample_info
125  }
126} // impl
127
128// This structure is used to communicate just deserialized samples
129// from SimpleDatareader to DataReader
130#[derive(Debug, Clone)]
131pub struct DeserializedCacheChange<D: Keyed> {
132  pub(crate) receive_instant: Timestamp, /* 8 bytes, to be used as unique key in internal data
133                                          * structures */
134  pub(crate) writer_guid: GUID,               // 8 bytes
135  pub(crate) sequence_number: SequenceNumber, // 8 bytes
136  pub(crate) write_options: WriteOptions,     // 16 bytes
137
138  // the data sample (or key) itself is stored here
139  pub(crate) sample: Sample<D, D::K>, /* TODO: make this a Box<> for easier detaching an
140                                       * reattaching to somewhere else */
141}
142
143impl<D: Keyed> DeserializedCacheChange<D> {
144  pub fn new(receive_instant: Timestamp, cc: &CacheChange, deserialized: Sample<D, D::K>) -> Self {
145    DeserializedCacheChange {
146      receive_instant,
147      writer_guid: cc.writer_guid,
148      sequence_number: cc.sequence_number,
149      write_options: cc.write_options.clone(),
150      sample: deserialized,
151    }
152  }
153}