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` `unwrap` and
15/// `as_ref` that correspond to methods of [`Result`](std::result::Result),
16/// which had been previously used for this purpose.
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  pub fn unwrap(self) -> D {
46    match self {
47      Sample::Value(d) => d,
48      Sample::Dispose(_k) => panic!("Unwrap called on a Sample with no data"),
49    }
50  }
51
52  pub const fn as_ref(&self) -> Sample<&D, &K> {
53    match *self {
54      Sample::Value(ref d) => Sample::Value(d),
55      Sample::Dispose(ref k) => Sample::Dispose(k),
56    }
57  }
58}
59
60/// A data sample and its associated [metadata](`SampleInfo`) received from a
61/// WITH_KEY Topic.
62///
63/// Note that [`no_key::DataSample`](crate::no_key::DataSample) and
64/// [`with_key::DataSample`](crate::with_key::DataSample) are two different
65/// structs.
66///
67/// We are using [`Sample`](crate::with_key::Sample) to replace the `valid_data`
68/// flag from the DDS spec, because when `valid_data = false`, the application
69/// should not be able to access any data.
70///
71/// Sample usage:
72/// * `Sample::Value(d)` means `valid_data == true` and there is a sample `d`.
73/// * `Sample::Dispose(k)` means `valid_data == false`, no sample exists, but
74///   only a Key `k` and instance_state has changed.
75///
76/// See also DDS spec v1.4 Section 2.2.2.5.4.
77#[derive(PartialEq, Debug)]
78pub struct DataSample<D: Keyed> {
79  pub(crate) sample_info: SampleInfo, // TODO: Can we somehow make this lazily evaluated?
80
81  pub(crate) value: Sample<D, D::K>,
82}
83
84impl<D> DataSample<D>
85where
86  D: Keyed,
87{
88  pub(crate) fn new(sample_info: SampleInfo, value: Sample<D, D::K>) -> Self {
89    Self { sample_info, value }
90  }
91
92  // convenience shorthand to get the key directly, without digging out the
93  // "value"
94  pub fn key(&self) -> D::K {
95    match &self.value {
96      Sample::Value(d) => d.key(),
97      Sample::Dispose(k) => k.clone(),
98    }
99  } // fn
100
101  pub fn value(&self) -> &Sample<D, D::K> {
102    &self.value
103  }
104
105  pub fn into_value(self) -> Sample<D, D::K> {
106    self.value
107  }
108
109  pub fn sample_info(&self) -> &SampleInfo {
110    &self.sample_info
111  }
112
113  pub fn sample_info_mut(&mut self) -> &mut SampleInfo {
114    &mut self.sample_info
115  }
116} // impl
117
118// This structure is used to communicate just deserialized samples
119// from SimpleDatareader to DataReader
120#[derive(Debug, Clone)]
121pub struct DeserializedCacheChange<D: Keyed> {
122  pub(crate) receive_instant: Timestamp, /* 8 bytes, to be used as unique key in internal data
123                                          * structures */
124  pub(crate) writer_guid: GUID,               // 8 bytes
125  pub(crate) sequence_number: SequenceNumber, // 8 bytes
126  pub(crate) write_options: WriteOptions,     // 16 bytes
127
128  // the data sample (or key) itself is stored here
129  pub(crate) sample: Sample<D, D::K>, /* TODO: make this a Box<> for easier detaching an
130                                       * reattaching to somewhere else */
131}
132
133impl<D: Keyed> DeserializedCacheChange<D> {
134  pub fn new(receive_instant: Timestamp, cc: &CacheChange, deserialized: Sample<D, D::K>) -> Self {
135    DeserializedCacheChange {
136      receive_instant,
137      writer_guid: cc.writer_guid,
138      sequence_number: cc.sequence_number,
139      write_options: cc.write_options.clone(),
140      sample: deserialized,
141    }
142  }
143}