Skip to main content

rustdds/dds/with_key/
datareader.rs

1use std::{
2  io,
3  pin::Pin,
4  sync::{Arc, Mutex, MutexGuard},
5  task::{Context, Poll},
6};
7
8#[allow(unused_imports)]
9use log::{debug, error, info, trace, warn};
10use futures::stream::{FusedStream, Stream};
11
12use super::datasample_cache::DataSampleCache;
13use crate::{
14  dds::{
15    adapters::with_key::{DefaultDecoder, *},
16    key::*,
17    qos::*,
18    readcondition::*,
19    result::ReadResult,
20    statusevents::*,
21    with_key::{datasample::*, simpledatareader::*},
22    ReadError,
23  },
24  discovery::sedp_messages::PublicationBuiltinTopicData,
25  serialization::CDRDeserializerAdapter,
26  structure::{duration::Duration, entity::RTPSEntity, guid::GUID, time::Timestamp},
27};
28
29/// Simplified type for CDR encoding
30pub type DataReaderCdr<D> = DataReader<D, CDRDeserializerAdapter<D>>;
31
32/// Parameter for reading [Readers](../struct.With_Key_DataReader.html) data
33/// with key or with next from current key.
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum SelectByKey {
36  This,
37  Next,
38}
39
40/// DDS DataReader for with_key topics.
41///
42/// # Examples
43///
44/// ```
45/// use serde::{Serialize, Deserialize};
46/// use rustdds::*;
47/// use rustdds::with_key::DataReader;
48/// use rustdds::serialization::CDRDeserializerAdapter;
49///
50/// let domain_participant = DomainParticipant::new(0).unwrap();
51/// let qos = QosPolicyBuilder::new().build();
52/// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
53///
54/// #[derive(Serialize, Deserialize)]
55/// struct SomeType { a: i32 }
56/// impl Keyed for SomeType {
57///   type K = i32;
58///
59///   fn key(&self) -> Self::K {
60///     self.a
61///   }
62/// }
63///
64/// // WithKey is important
65/// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
66/// let data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None);
67/// ```
68///
69/// *Note:* Many DataReader methods require mutable access to `self`, because
70/// they need to mutate the datasample cache, which is an essential content of
71/// this struct.
72pub struct DataReader<D: Keyed, DA: DeserializerAdapter<D> = CDRDeserializerAdapter<D>> {
73  simple_data_reader: SimpleDataReader<D, DA>,
74  datasample_cache: DataSampleCache<D>, // DataReader-local cache of deserialized samples
75}
76
77impl<D: 'static, DA> DataReader<D, DA>
78where
79  D: Keyed,
80  DA: DeserializerAdapter<D>,
81{
82  pub(crate) fn from_simple_data_reader(simple_data_reader: SimpleDataReader<D, DA>) -> Self {
83    let dsc = DataSampleCache::new(simple_data_reader.qos().clone());
84
85    Self {
86      simple_data_reader,
87      datasample_cache: dsc,
88    }
89  }
90}
91
92impl<D: 'static, DA> DataReader<D, DA>
93where
94  D: Keyed,
95  DA: DeserializerAdapter<D> + DefaultDecoder<D>,
96{
97  // Gets all unseen cache_changes from the TopicCache. Deserializes
98  // the serialized payload and stores the DataSamples (the actual data and the
99  // samplestate) to local container, datasample_cache.
100  fn fill_and_lock_local_datasample_cache(&mut self) -> ReadResult<()> {
101    while let Some(dcc) = self.simple_data_reader.try_take_one()? {
102      self
103        .datasample_cache
104        .fill_from_deserialized_cache_change(dcc);
105    }
106    Ok(())
107  }
108
109  fn drain_read_notifications(&self) {
110    self.simple_data_reader.drain_read_notifications();
111  }
112
113  fn select_keys_for_access(&self, read_condition: ReadCondition) -> Vec<(Timestamp, D::K)> {
114    self.datasample_cache.select_keys_for_access(read_condition)
115  }
116
117  fn take_by_keys(&mut self, keys: &[(Timestamp, D::K)]) -> Vec<DataSample<D>> {
118    self.datasample_cache.take_by_keys(keys)
119  }
120
121  fn take_bare_by_keys(&mut self, keys: &[(Timestamp, D::K)]) -> Vec<Sample<D, D::K>> {
122    self.datasample_cache.take_bare_by_keys(keys)
123  }
124
125  fn select_instance_keys_for_access(
126    &self,
127    instance: &D::K,
128    rc: ReadCondition,
129  ) -> Vec<(Timestamp, D::K)> {
130    self
131      .datasample_cache
132      .select_instance_keys_for_access(instance, rc)
133  }
134
135  /// Reads amount of samples found with `max_samples` and `read_condition`
136  /// parameters.
137  ///
138  /// # Arguments
139  ///
140  /// * `max_samples` - Limits maximum amount of samples read
141  /// * `read_condition` - Limits results by condition
142  ///
143  /// # Examples
144  ///
145  /// ```
146  /// # use serde::{Serialize, Deserialize};
147  /// # use rustdds::*;
148  /// # use rustdds::with_key::DataReader;
149  /// # use rustdds::serialization::CDRDeserializerAdapter;
150  ///
151  /// let domain_participant = DomainParticipant::new(0).unwrap();
152  /// let qos = QosPolicyBuilder::new().build();
153  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
154  /// #
155  /// # #[derive(Serialize, Deserialize)]
156  /// # struct SomeType { a: i32 }
157  /// # impl Keyed for SomeType {
158  /// #   type K = i32;
159  /// #
160  /// #   fn key(&self) -> Self::K {
161  /// #     self.a
162  /// #   }
163  /// # }
164  ///
165  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
166  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
167  ///
168  /// // Wait for data to arrive...
169  ///
170  /// if let Ok(datas) = data_reader.read(10, ReadCondition::not_read()) {
171  ///   for data in datas.iter() {
172  ///     // do something
173  ///   }
174  /// }
175  /// ```
176  pub fn read(
177    &mut self,
178    max_samples: usize,
179    read_condition: ReadCondition,
180  ) -> ReadResult<Vec<DataSample<&D>>> {
181    // Clear notification buffer. This must be done first to avoid race conditions.
182    self.drain_read_notifications();
183    self.fill_and_lock_local_datasample_cache()?;
184
185    let mut selected = self.select_keys_for_access(read_condition);
186    selected.truncate(max_samples);
187
188    let result = self.datasample_cache.read_by_keys(&selected);
189
190    Ok(result)
191  }
192
193  /// Takes amount of sample found with `max_samples` and `read_condition`
194  /// parameters.
195  ///
196  /// # Arguments
197  ///
198  /// * `max_samples` - Limits maximum amount of samples read
199  /// * `read_condition` - Limits results by condition
200  ///
201  /// # Examples
202  ///
203  /// ```
204  /// # use serde::{Serialize, Deserialize};
205  /// # use rustdds::*;
206  /// # use rustdds::with_key::DataReader;
207  /// # use rustdds::serialization::CDRDeserializerAdapter;
208  ///
209  /// let domain_participant = DomainParticipant::new(0).unwrap();
210  /// let qos = QosPolicyBuilder::new().build();
211  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
212  /// #
213  /// # #[derive(Serialize, Deserialize)]
214  /// # struct SomeType { a: i32 }
215  /// # impl Keyed for SomeType {
216  /// #   type K = i32;
217  /// #
218  /// #   fn key(&self) -> Self::K {
219  /// #     self.a
220  /// #   }
221  /// # }
222  ///
223  /// // WithKey is important
224  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
225  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
226  ///
227  /// // Wait for data to arrive...
228  ///
229  /// if let Ok(datas) = data_reader.take(10, ReadCondition::not_read()) {
230  ///   for data in datas.iter() {
231  ///     // do something
232  ///   }
233  /// }
234  /// ```
235  pub fn take(
236    &mut self,
237    max_samples: usize,
238    read_condition: ReadCondition,
239  ) -> ReadResult<Vec<DataSample<D>>> {
240    // Clear notification buffer. This must be done first to avoid race conditions.
241    self.drain_read_notifications();
242
243    self.fill_and_lock_local_datasample_cache()?;
244    let mut selected = self.select_keys_for_access(read_condition);
245    trace!("take selected count = {}", selected.len());
246    selected.truncate(max_samples);
247
248    let result = self.take_by_keys(&selected);
249    trace!("take taken count = {}", result.len());
250
251    Ok(result)
252  }
253
254  /// Reads next unread sample
255  ///
256  /// # Examples
257  ///
258  /// ```
259  /// # use serde::{Serialize, Deserialize};
260  /// # use rustdds::*;
261  /// # use rustdds::with_key::DataReader;
262  /// # use rustdds::serialization::CDRDeserializerAdapter;
263  /// #
264  /// let domain_participant = DomainParticipant::new(0).unwrap();
265  /// let qos = QosPolicyBuilder::new().build();
266  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
267  /// #
268  /// # #[derive(Serialize, Deserialize)]
269  /// # struct SomeType { a: i32 }
270  /// # impl Keyed for SomeType {
271  /// #   type K = i32;
272  /// #
273  /// #   fn key(&self) -> Self::K {
274  /// #     self.a
275  /// #   }
276  /// # }
277  ///
278  /// // WithKey is important
279  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
280  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
281  ///
282  /// // Wait for data to arrive...
283  ///
284  /// while let Ok(Some(data)) = data_reader.read_next_sample() {
285  ///   // do something
286  /// }
287  /// ```
288  pub fn read_next_sample(&mut self) -> ReadResult<Option<DataSample<&D>>> {
289    let mut ds = self.read(1, ReadCondition::not_read())?;
290    Ok(ds.pop())
291  }
292
293  /// Takes next unread sample
294  ///
295  /// # Examples
296  ///
297  /// ```
298  /// # use serde::{Serialize, Deserialize};
299  /// # use rustdds::*;
300  /// # use rustdds::with_key::DataReader;
301  /// # use rustdds::serialization::CDRDeserializerAdapter;
302  /// #
303  /// let domain_participant = DomainParticipant::new(0).unwrap();
304  /// let qos = QosPolicyBuilder::new().build();
305  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
306  /// #
307  /// # #[derive(Serialize, Deserialize)]
308  /// # struct SomeType { a: i32 }
309  /// # impl Keyed for SomeType {
310  /// #   type K = i32;
311  /// #
312  /// #   fn key(&self) -> Self::K {
313  /// #     self.a
314  /// #   }
315  /// # }
316  ///
317  /// // WithKey is important
318  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
319  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
320  ///
321  /// // Wait for data to arrive...
322  ///
323  /// while let Ok(Some(data)) = data_reader.take_next_sample() {
324  ///   // do something
325  /// }
326  /// ```
327  pub fn take_next_sample(&mut self) -> ReadResult<Option<DataSample<D>>> {
328    let mut ds = self.take(1, ReadCondition::not_read())?;
329    Ok(ds.pop())
330  }
331
332  // Iterator interface
333
334  fn read_bare(
335    &mut self,
336    max_samples: usize,
337    read_condition: ReadCondition,
338  ) -> ReadResult<Vec<Sample<&D, D::K>>> {
339    self.drain_read_notifications();
340    self.fill_and_lock_local_datasample_cache()?;
341
342    let mut selected = self.select_keys_for_access(read_condition);
343    selected.truncate(max_samples);
344
345    let result = self.datasample_cache.read_bare_by_keys(&selected);
346
347    Ok(result)
348  }
349
350  fn take_bare(
351    &mut self,
352    max_samples: usize,
353    read_condition: ReadCondition,
354  ) -> ReadResult<Vec<Sample<D, D::K>>> {
355    // Clear notification buffer. This must be done first to avoid race conditions.
356    self.drain_read_notifications();
357    self.fill_and_lock_local_datasample_cache()?;
358
359    let mut selected = self.select_keys_for_access(read_condition);
360    trace!("take bare selected count = {}", selected.len());
361    selected.truncate(max_samples);
362
363    let result = self.take_bare_by_keys(&selected);
364    trace!("take bare taken count = {}", result.len());
365
366    Ok(result)
367  }
368
369  /// Produces an iterator over the currently available NOT_READ samples.
370  /// Yields only payload data, not SampleInfo metadata
371  /// This is not called `iter()` because it takes a mutable reference to self.
372  ///
373  /// # Examples
374  ///
375  /// ```
376  /// # use serde::{Serialize, Deserialize};
377  /// # use rustdds::*;
378  /// # use rustdds::with_key::DataReader;
379  /// # use rustdds::serialization::CDRDeserializerAdapter;
380  /// #
381  /// let domain_participant = DomainParticipant::new(0).unwrap();
382  /// let qos = QosPolicyBuilder::new().build();
383  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
384  /// #
385  /// # #[derive(Serialize, Deserialize)]
386  /// # struct SomeType { a: i32 }
387  /// # impl Keyed for SomeType {
388  /// #   type K = i32;
389  /// #
390  /// #   fn key(&self) -> Self::K {
391  /// #     self.a
392  /// #   }
393  /// # }
394  ///
395  /// // WithKey is important
396  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
397  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
398  ///
399  /// // Wait for data to arrive...
400  ///
401  /// for data in data_reader.iterator() {
402  ///   // do something
403  /// }
404  /// ```
405  pub fn iterator(&mut self) -> ReadResult<impl Iterator<Item = Sample<&D, D::K>>> {
406    // TODO: We could come up with a more efficient implementation than wrapping a
407    // read call
408    Ok(
409      self
410        .read_bare(usize::MAX, ReadCondition::not_read())?
411        .into_iter(),
412    )
413  }
414
415  /// Produces an iterator over the samples filtered by a given condition.
416  /// Yields only payload data, not SampleInfo metadata
417  ///
418  /// # Examples
419  ///
420  /// ```
421  /// # use serde::{Serialize, Deserialize};
422  /// # use rustdds::*;
423  /// # use rustdds::with_key::DataReader;
424  /// # use rustdds::serialization::CDRDeserializerAdapter;
425  ///
426  /// let domain_participant = DomainParticipant::new(0).unwrap();
427  /// let qos = QosPolicyBuilder::new().build();
428  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
429  /// #
430  /// # #[derive(Serialize, Deserialize)]
431  /// # struct SomeType { a: i32 }
432  /// # impl Keyed for SomeType {
433  /// #   type K = i32;
434  /// #
435  /// #   fn key(&self) -> Self::K {
436  /// #     self.a
437  /// #   }
438  /// # }
439  ///
440  /// // WithKey is important
441  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
442  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
443  ///
444  /// // Wait for data to arrive...
445  ///
446  /// for data in data_reader.conditional_iterator(ReadCondition::any()) {
447  ///   // do something
448  /// }
449  /// ```
450  pub fn conditional_iterator(
451    &mut self,
452    read_condition: ReadCondition,
453  ) -> ReadResult<impl Iterator<Item = Sample<&D, D::K>>> {
454    // TODO: We could come up with a more efficient implementation than wrapping a
455    // read call
456    Ok(self.read_bare(usize::MAX, read_condition)?.into_iter())
457  }
458
459  /// Produces an iterator over the currently available NOT_READ samples.
460  /// Yields only payload data, not SampleInfo metadata
461  /// Removes samples from `DataReader`.
462  /// <strong>Note!</strong> If the iterator is only partially consumed, all the
463  /// samples it could have provided are still removed from the `Datareader`.
464  ///
465  /// # Examples
466  ///
467  /// ```
468  /// # use serde::{Serialize, Deserialize};
469  /// # use rustdds::*;
470  /// # use rustdds::with_key::DataReader;
471  /// # use rustdds::serialization::CDRDeserializerAdapter;
472  /// #
473  /// let domain_participant = DomainParticipant::new(0).unwrap();
474  /// let qos = QosPolicyBuilder::new().build();
475  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
476  /// #
477  /// # #[derive(Serialize, Deserialize)]
478  /// # struct SomeType { a: i32 }
479  /// # impl Keyed for SomeType {
480  /// #   type K = i32;
481  /// #
482  /// #   fn key(&self) -> Self::K {
483  /// #     self.a
484  /// #   }
485  /// # }
486  ///
487  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
488  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
489  ///
490  /// // Wait for data to arrive...
491  ///
492  /// for data in data_reader.into_iterator() {
493  ///   // do something
494  /// }
495  /// ```
496  pub fn into_iterator(&mut self) -> ReadResult<impl Iterator<Item = Sample<D, D::K>>> {
497    // TODO: We could come up with a more efficient implementation than wrapping a
498    // take call
499    Ok(
500      self
501        .take_bare(usize::MAX, ReadCondition::not_read())?
502        .into_iter(),
503    )
504  }
505
506  /// Produces an iterator over the samples filtered by the given condition.
507  /// Yields only payload data, not SampleInfo metadata
508  /// <strong>Note!</strong> If the iterator is only partially consumed, all the
509  /// samples it could have provided are still removed from the `Datareader`.
510  ///
511  /// # Examples
512  ///
513  /// ```
514  /// # use serde::{Serialize, Deserialize};
515  /// # use rustdds::*;
516  /// # use rustdds::with_key::DataReader;
517  /// # use rustdds::serialization::CDRDeserializerAdapter;
518  ///
519  /// let domain_participant = DomainParticipant::new(0).unwrap();
520  /// let qos = QosPolicyBuilder::new().build();
521  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
522  /// #
523  /// # #[derive(Serialize, Deserialize)]
524  /// # struct SomeType { a: i32 }
525  /// # impl Keyed for SomeType {
526  /// #   type K = i32;
527  /// #
528  /// #   fn key(&self) -> Self::K {
529  /// #     self.a
530  /// #   }
531  /// # }
532  ///
533  /// // WithKey is important
534  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
535  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
536  ///
537  /// // Wait for data to arrive...
538  ///
539  /// for data in data_reader.into_conditional_iterator(ReadCondition::not_read()) {
540  ///   // do something
541  /// }
542  /// ```
543  pub fn into_conditional_iterator(
544    &mut self,
545    read_condition: ReadCondition,
546  ) -> ReadResult<impl Iterator<Item = Sample<D, D::K>>> {
547    // TODO: We could come up with a more efficient implementation than wrapping a
548    // take call
549    Ok(self.take_bare(usize::MAX, read_condition)?.into_iter())
550  }
551
552  // ----------------------------------------------------------------------------
553  // ----------------------------------------------------------------------------
554
555  fn infer_key(
556    &self,
557    instance_key: Option<<D as Keyed>::K>,
558    this_or_next: SelectByKey,
559  ) -> Option<<D as Keyed>::K> {
560    match instance_key {
561      Some(k) => match this_or_next {
562        SelectByKey::This => Some(k),
563        SelectByKey::Next => self.datasample_cache.next_key(&k),
564      },
565      None => self.datasample_cache.instance_map.keys().next().cloned(),
566    }
567  }
568
569  /// Works similarly to read(), but will return only samples from a specific
570  /// instance. The instance is specified by an optional key. In case the key
571  /// is not specified, the smallest (in key order) instance is selected.
572  /// If a key is specified, then the parameter this_or_next specifies whether
573  /// to access the instance with specified key or the following one, in key
574  /// order.
575  ///
576  /// This should cover DDS DataReader methods read_instance,
577  /// read_next_instance, read_next_instance_w_condition.
578  ///
579  /// # Examples
580  ///
581  /// ```
582  /// # use serde::{Serialize, Deserialize};
583  /// # use rustdds::*;
584  /// # use rustdds::with_key::DataReader;
585  /// # use rustdds::serialization::CDRDeserializerAdapter;
586  ///
587  /// let domain_participant = DomainParticipant::new(0).unwrap();
588  /// let qos = QosPolicyBuilder::new().build();
589  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
590  /// #
591  /// # #[derive(Serialize, Deserialize)]
592  /// # struct SomeType { a: i32 }
593  /// # impl Keyed for SomeType {
594  /// #   type K = i32;
595  /// #
596  /// #   fn key(&self) -> Self::K {
597  /// #     self.a
598  /// #   }
599  /// # }
600  ///
601  /// // WithKey is important
602  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
603  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
604  ///
605  /// // Wait for data to arrive...
606  ///
607  /// if let Ok(datas) = data_reader.read_instance(10, ReadCondition::any(), Some(3), SelectByKey::This) {
608  ///   for data in datas.iter() {
609  ///     // do something
610  ///   }
611  /// }
612  /// ```
613  pub fn read_instance(
614    &mut self,
615    max_samples: usize,
616    read_condition: ReadCondition,
617    // Select only samples from instance specified by key. In case of None, select the
618    // "smallest" instance as specified by the key type Ord trait.
619    instance_key: Option<<D as Keyed>::K>,
620    // This = Select instance specified by key.
621    // Next = select next instance in the order specified by Ord on keys.
622    this_or_next: SelectByKey,
623  ) -> ReadResult<Vec<DataSample<&D>>> {
624    self.drain_read_notifications();
625    self.fill_and_lock_local_datasample_cache()?;
626
627    let key = match Self::infer_key(self, instance_key, this_or_next) {
628      Some(k) => k,
629      None => return Ok(Vec::new()),
630    };
631
632    let mut selected = self
633      .datasample_cache
634      .select_instance_keys_for_access(&key, read_condition);
635    selected.truncate(max_samples);
636
637    let result = self.datasample_cache.read_by_keys(&selected);
638
639    Ok(result)
640  }
641
642  /// Similar to read_instance, but will return owned datasamples
643  /// This should cover DDS DataReader methods take_instance,
644  /// take_next_instance, take_next_instance_w_condition.
645  ///
646  /// # Examples
647  ///
648  /// ```
649  /// # use serde::{Serialize, Deserialize};
650  /// # use rustdds::*;
651  /// # use rustdds::with_key::DataReader;
652  /// # use rustdds::serialization::CDRDeserializerAdapter;
653  ///
654  /// let domain_participant = DomainParticipant::new(0).unwrap();
655  /// let qos = QosPolicyBuilder::new().build();
656  /// let subscriber = domain_participant.create_subscriber(&qos).unwrap();
657  /// #
658  /// # #[derive(Serialize, Deserialize)]
659  /// # struct SomeType { a: i32 }
660  /// # impl Keyed for SomeType {
661  /// #   type K = i32;
662  /// #
663  /// #   fn key(&self) -> Self::K {
664  /// #     self.a
665  /// #   }
666  /// # }
667  ///
668  /// // WithKey is important
669  /// let topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::WithKey).unwrap();
670  /// let mut data_reader = subscriber.create_datareader::<SomeType, CDRDeserializerAdapter<_>>(&topic, None).unwrap();
671  ///
672  /// // Wait for data to arrive...
673  ///
674  /// if let Ok(datas) = data_reader.take_instance(10, ReadCondition::any(), Some(3), SelectByKey::Next) {
675  ///   for data in datas.iter() {
676  ///     // do something
677  ///   }
678  /// }
679  /// ```
680  pub fn take_instance(
681    &mut self,
682    max_samples: usize,
683    read_condition: ReadCondition,
684    // Select only samples from instance specified by key. In case of None, select the
685    // "smallest" instance as specified by the key type Ord trait.
686    instance_key: Option<<D as Keyed>::K>,
687    // This = Select instance specified by key.
688    // Next = select next instance in the order specified by Ord on keys.
689    this_or_next: SelectByKey,
690  ) -> ReadResult<Vec<DataSample<D>>> {
691    // Clear notification buffer. This must be done first to avoid race conditions.
692    self.drain_read_notifications();
693
694    self.fill_and_lock_local_datasample_cache()?;
695
696    let key = match self.infer_key(instance_key, this_or_next) {
697      Some(k) => k,
698      None => return Ok(Vec::new()),
699    };
700
701    let mut selected = self.select_instance_keys_for_access(&key, read_condition);
702    selected.truncate(max_samples);
703
704    let result = self.take_by_keys(&selected);
705
706    Ok(result)
707  }
708
709  /// Placeholder only — not implemented. **Will panic if called.**
710  ///
711  /// When implemented, this should return `true` if all historical data was
712  /// received before the timeout and `false` otherwise.
713  ///
714  /// # Panics
715  ///
716  /// Always panics. This method is a placeholder and is not implemented.
717  #[deprecated(note = "placeholder only; will panic if called")]
718  pub fn wait_for_historical_data(&mut self, _max_wait: Duration) -> bool {
719    unreachable!("wait_for_historical_data is a placeholder only and must not be called")
720  }
721
722  // Spec calls for two separate functions:
723  // get_matched_publications returns a list of handles
724  // get_matched_publication_data returns PublicationBuiltinTopicData for a handle
725  // But we do not believe in handle-oriented programming, so just return
726  // the actual data right away. Since the handles are quite opaque, about the
727  // only thing that could be done with the handles would be counting how many
728  // we got.
729
730  pub fn get_matched_publications(&self) -> impl Iterator<Item = PublicationBuiltinTopicData> {
731    // TODO: Obviously not implemented
732    vec![].into_iter()
733  }
734
735  /// An async stream for reading the (bare) data samples.
736  /// The resulting Stream can be used to get another stream of status events.
737  pub fn async_bare_sample_stream(self) -> BareDataReaderStream<D, DA> {
738    BareDataReaderStream {
739      datareader: Arc::new(Mutex::new(self)),
740    }
741  }
742
743  /// An async stream for reading the data samples.
744  /// The resulting Stream can be used to get another stream of status events.
745  pub fn async_sample_stream(self) -> DataReaderStream<D, DA> {
746    DataReaderStream {
747      datareader: Arc::new(Mutex::new(self)),
748    }
749  }
750} // impl
751
752// -------------------
753
754impl<D, DA> mio_06::Evented for DataReader<D, DA>
755where
756  D: Keyed,
757  DA: DeserializerAdapter<D>,
758{
759  // We just delegate all the operations to notification_receiver, since it
760  // already implements mio_06::Evented
761  fn register(
762    &self,
763    poll: &mio_06::Poll,
764    token: mio_06::Token,
765    interest: mio_06::Ready,
766    opts: mio_06::PollOpt,
767  ) -> io::Result<()> {
768    self
769      .simple_data_reader
770      .register(poll, token, interest, opts)
771  }
772
773  fn reregister(
774    &self,
775    poll: &mio_06::Poll,
776    token: mio_06::Token,
777    interest: mio_06::Ready,
778    opts: mio_06::PollOpt,
779  ) -> io::Result<()> {
780    self
781      .simple_data_reader
782      .reregister(poll, token, interest, opts)
783  }
784
785  fn deregister(&self, poll: &mio_06::Poll) -> io::Result<()> {
786    self.simple_data_reader.deregister(poll)
787  }
788}
789
790#[cfg(feature = "mio_08")]
791impl<D, DA> mio_08::event::Source for DataReader<D, DA>
792where
793  D: Keyed,
794  DA: DeserializerAdapter<D>,
795{
796  fn register(
797    &mut self,
798    registry: &mio_08::Registry,
799    token: mio_08::Token,
800    interests: mio_08::Interest,
801  ) -> io::Result<()> {
802    // SimpleDataReader implements .register() for two traits, so need to
803    // use disambiguation syntax to call .register() here.
804    <SimpleDataReader<D, DA> as mio_08::event::Source>::register(
805      &mut self.simple_data_reader,
806      registry,
807      token,
808      interests,
809    )
810  }
811
812  fn reregister(
813    &mut self,
814    registry: &mio_08::Registry,
815    token: mio_08::Token,
816    interests: mio_08::Interest,
817  ) -> io::Result<()> {
818    <SimpleDataReader<D, DA> as mio_08::event::Source>::reregister(
819      &mut self.simple_data_reader,
820      registry,
821      token,
822      interests,
823    )
824  }
825
826  fn deregister(&mut self, registry: &mio_08::Registry) -> io::Result<()> {
827    <SimpleDataReader<D, DA> as mio_08::event::Source>::deregister(
828      &mut self.simple_data_reader,
829      registry,
830    )
831  }
832}
833
834impl<'a, D, DA> StatusEvented<'a, DataReaderStatus, SimpleDataReaderEventStream<'a, D, DA>>
835  for DataReader<D, DA>
836where
837  D: Keyed + 'static,
838  DA: DeserializerAdapter<D>,
839{
840  fn as_status_evented(&mut self) -> &dyn mio_06::Evented {
841    self.simple_data_reader.as_status_evented()
842  }
843
844  #[cfg(feature = "mio_08")]
845  fn as_status_source(&mut self) -> &mut dyn mio_08::event::Source {
846    self.simple_data_reader.as_status_source()
847  }
848
849  fn as_async_status_stream(&'a self) -> SimpleDataReaderEventStream<'a, D, DA> {
850    self.simple_data_reader.as_async_status_stream()
851  }
852
853  fn try_recv_status(&self) -> Option<DataReaderStatus> {
854    self.simple_data_reader.try_recv_status()
855  }
856}
857
858impl<D, DA> HasQoSPolicy for DataReader<D, DA>
859where
860  D: Keyed + 'static,
861  DA: DeserializerAdapter<D>,
862{
863  fn qos(&self) -> QosPolicies {
864    self.simple_data_reader.qos().clone()
865  }
866}
867
868impl<D, DA> RTPSEntity for DataReader<D, DA>
869where
870  D: Keyed + 'static,
871  DA: DeserializerAdapter<D>,
872{
873  fn guid(&self) -> GUID {
874    self.simple_data_reader.guid()
875  }
876}
877
878// ----------------------------------------------
879// ----------------------------------------------
880
881// Async interface to the (bare) DataReader
882
883pub struct BareDataReaderStream<
884  D: Keyed + 'static,
885  DA: DeserializerAdapter<D> + 'static = CDRDeserializerAdapter<D>,
886> {
887  datareader: Arc<Mutex<DataReader<D, DA>>>,
888}
889
890impl<D, DA> BareDataReaderStream<D, DA>
891where
892  D: Keyed + 'static,
893  DA: DeserializerAdapter<D>,
894{
895  /// Get a stream of status events
896  pub fn async_event_stream(&self) -> DataReaderEventStream<D, DA> {
897    DataReaderEventStream {
898      datareader: Arc::clone(&self.datareader),
899    }
900  }
901  fn lock_datareader(&self) -> ReadResult<MutexGuard<'_, DataReader<D, DA>>> {
902    self.datareader.lock().map_err(|e| ReadError::Poisoned {
903      reason: format!("BareDataReaderStream could not lock datareader: {e:?}"),
904    })
905  }
906}
907
908// https://users.rust-lang.org/t/take-in-impl-future-cannot-borrow-data-in-a-dereference-of-pin/52042
909impl<D, DA> Unpin for BareDataReaderStream<D, DA>
910where
911  D: Keyed + 'static,
912  DA: DeserializerAdapter<D>,
913{
914}
915
916impl<D, DA> Stream for BareDataReaderStream<D, DA>
917where
918  D: Keyed + 'static,
919  DA: DeserializerAdapter<D> + DefaultDecoder<D>,
920{
921  type Item = ReadResult<Sample<D, D::K>>;
922
923  fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
924    debug!("poll_next");
925    let mut datareader = match self.lock_datareader() {
926      Ok(g) => g,
927      Err(e) => return Poll::Ready(Some(Err(e))),
928    }; //TODO: Upgrade to ?-operator: https://github.com/rust-lang/rust/issues/84277
929
930    match datareader.take_bare(1, ReadCondition::not_read()) {
931      Err(e) =>
932      // DDS fails
933      {
934        Poll::Ready(Some(Err(e)))
935      }
936
937      Ok(mut v) => {
938        match v.pop() {
939          Some(d) => Poll::Ready(Some(Ok(d))),
940          None => {
941            // Did not get any data.
942            // --> Store waker.
943            // 1. synchronously store waker to background thread (must rendezvous)
944            // 2. try take_bare again, in case something arrived just now
945            // 3. if nothing still, return pending.
946            datareader
947              .simple_data_reader
948              .set_waker(Some(cx.waker().clone()));
949            match datareader.take_bare(1, ReadCondition::not_read()) {
950              Err(e) => Poll::Ready(Some(Err(e))),
951              Ok(mut v) => match v.pop() {
952                None => Poll::Pending,
953                Some(d) => Poll::Ready(Some(Ok(d))),
954              },
955            }
956          }
957        }
958      }
959    }
960  }
961}
962
963impl<D, DA> FusedStream for BareDataReaderStream<D, DA>
964where
965  D: Keyed + 'static,
966  DA: DeserializerAdapter<D> + DefaultDecoder<D>,
967{
968  fn is_terminated(&self) -> bool {
969    false // Never terminate. This means it is always valid to call poll_next().
970  }
971}
972
973// Async interface to the (non-bare) DataReader
974
975pub struct DataReaderStream<
976  D: Keyed + 'static,
977  DA: DeserializerAdapter<D> + 'static = CDRDeserializerAdapter<D>,
978> {
979  datareader: Arc<Mutex<DataReader<D, DA>>>,
980}
981
982impl<D, DA> DataReaderStream<D, DA>
983where
984  D: Keyed + 'static,
985  DA: DeserializerAdapter<D>,
986{
987  /// Get a stream of status events
988  pub fn async_event_stream(&self) -> DataReaderEventStream<D, DA> {
989    DataReaderEventStream {
990      datareader: Arc::clone(&self.datareader),
991    }
992  }
993  fn lock_datareader(&self) -> ReadResult<MutexGuard<'_, DataReader<D, DA>>> {
994    self.datareader.lock().map_err(|e| ReadError::Poisoned {
995      reason: format!("DataReaderStream could not lock datareader: {e:?}"),
996    })
997  }
998}
999
1000// https://users.rust-lang.org/t/take-in-impl-future-cannot-borrow-data-in-a-dereference-of-pin/52042
1001impl<D, DA> Unpin for DataReaderStream<D, DA>
1002where
1003  D: Keyed + 'static,
1004  DA: DeserializerAdapter<D>,
1005{
1006}
1007
1008impl<D, DA> Stream for DataReaderStream<D, DA>
1009where
1010  D: Keyed + 'static,
1011  DA: DeserializerAdapter<D> + DefaultDecoder<D>,
1012{
1013  type Item = ReadResult<DataSample<D>>;
1014
1015  fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1016    debug!("poll_next");
1017    let mut datareader = match self.lock_datareader() {
1018      Ok(g) => g,
1019      Err(e) => return Poll::Ready(Some(Err(e))),
1020    }; //TODO: Upgrade to ?-operator: https://github.com/rust-lang/rust/issues/84277
1021
1022    match datareader.take(1, ReadCondition::not_read()) {
1023      Err(e) =>
1024      // DDS fails
1025      {
1026        Poll::Ready(Some(Err(e)))
1027      }
1028
1029      Ok(mut v) => {
1030        match v.pop() {
1031          Some(d) => Poll::Ready(Some(Ok(d))),
1032          None => {
1033            // Did not get any data.
1034            // --> Store waker.
1035            // 1. synchronously store waker to background thread (must rendezvous)
1036            // 2. try take again, in case something arrived just now
1037            // 3. if nothing still, return pending.
1038            datareader
1039              .simple_data_reader
1040              .set_waker(Some(cx.waker().clone()));
1041            match datareader.take(1, ReadCondition::not_read()) {
1042              Err(e) => Poll::Ready(Some(Err(e))),
1043              Ok(mut v) => match v.pop() {
1044                None => Poll::Pending,
1045                Some(d) => Poll::Ready(Some(Ok(d))),
1046              },
1047            }
1048          }
1049        }
1050      }
1051    }
1052  }
1053}
1054
1055impl<D, DA> FusedStream for DataReaderStream<D, DA>
1056where
1057  D: Keyed + 'static,
1058  DA: DeserializerAdapter<D> + DefaultDecoder<D>,
1059{
1060  fn is_terminated(&self) -> bool {
1061    false // Never terminate. This means it is always valid to call poll_next().
1062  }
1063}
1064
1065// ----------------------------------------------------------------------------------------------------
1066// ----------------------------------------------------------------------------------------------------
1067
1068pub struct DataReaderEventStream<
1069  D: Keyed + 'static,
1070  DA: DeserializerAdapter<D> + 'static = CDRDeserializerAdapter<D>,
1071> {
1072  datareader: Arc<Mutex<DataReader<D, DA>>>,
1073}
1074
1075impl<D, DA> DataReaderEventStream<D, DA>
1076where
1077  D: Keyed + 'static,
1078  DA: DeserializerAdapter<D>,
1079{
1080  fn lock_datareader(&self) -> ReadResult<MutexGuard<'_, DataReader<D, DA>>> {
1081    self.datareader.lock().map_err(|e| ReadError::Poisoned {
1082      reason: format!("DataReaderEventStream could not lock datareader: {e:?}"),
1083    })
1084  }
1085}
1086
1087impl<D, DA> Stream for DataReaderEventStream<D, DA>
1088where
1089  D: Keyed + 'static,
1090  DA: DeserializerAdapter<D>,
1091{
1092  type Item = DataReaderStatus;
1093
1094  fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1095    let datareader = match self.lock_datareader() {
1096      Ok(g) => g,
1097      Err(_e) => return Poll::Ready(None),
1098      // If the locking failed, it is due to lock poisoning. This is not recoverable.
1099      // We just indicate that the stream of events has ended, because there is
1100      // no Result to return here.
1101    };
1102
1103    Pin::new(&mut datareader.simple_data_reader.as_async_status_stream()).poll_next(cx)
1104  }
1105}
1106
1107impl<D, DA> FusedStream for DataReaderEventStream<D, DA>
1108where
1109  D: Keyed + 'static,
1110  DA: DeserializerAdapter<D>,
1111{
1112  fn is_terminated(&self) -> bool {
1113    false // Never terminate. This means it is always valid to call poll_next().
1114  }
1115}
1116
1117// ----------------------------------------------------------------------------------------------------
1118// ----------------------------------------------------------------------------------------------------
1119// ----------------------------------------------------------------------------------------------------
1120// ----------------------------------------------------------------------------------------------------
1121// ----------------------------------------------------------------------------------------------------
1122// ----------------------------------------------------------------------------------------------------
1123
1124#[cfg(test)]
1125mod tests {
1126  use std::rc::Rc;
1127
1128  use bytes::Bytes;
1129  use mio_extras::channel as mio_channel;
1130  use log::info;
1131  use byteorder::LittleEndian;
1132
1133  use super::*;
1134  use crate::{
1135    dds::{
1136      participant::DomainParticipant,
1137      topic::{TopicDescription, TopicKind},
1138    },
1139    messages::submessages::{
1140      elements::serialized_payload::SerializedPayload, submessage_flag::*, submessages::Data,
1141    },
1142    mio_source,
1143    network::udp_sender::UDPSender,
1144    rtps::{
1145      message_receiver::*,
1146      reader::{Reader, ReaderIngredients},
1147    },
1148    serialization::to_vec,
1149    structure::{
1150      guid::{EntityId, EntityKind, GuidPrefix},
1151      sequence_number::SequenceNumber,
1152    },
1153    test::random_data::*,
1154    RepresentationIdentifier,
1155  };
1156
1157  #[test]
1158  fn read_and_take() {
1159    // Test the read and take methods of the DataReader
1160
1161    let dp = DomainParticipant::new(0).expect("Participant creation failed!");
1162
1163    let mut qos = QosPolicies::qos_none();
1164    qos.history = Some(policy::History::KeepAll); // Just for testing
1165
1166    let sub = dp.create_subscriber(&qos).unwrap();
1167    let topic = dp
1168      .create_topic(
1169        "dr read".to_string(),
1170        "read fn test?".to_string(),
1171        &qos,
1172        TopicKind::WithKey,
1173      )
1174      .unwrap();
1175
1176    let topic_cache =
1177      dp.dds_cache()
1178        .write()
1179        .unwrap()
1180        .add_new_topic(topic.name(), topic.get_type(), &topic.qos());
1181
1182    // Create a Reader
1183    let (notification_sender, _notification_receiver) = mio_channel::sync_channel::<()>(100);
1184    let (_notification_event_source, notification_event_sender) =
1185      mio_source::make_poll_channel().unwrap();
1186    let data_reader_waker = Arc::new(Mutex::new(None));
1187
1188    let (status_sender, _status_receiver) = sync_status_channel::<DataReaderStatus>(4).unwrap();
1189    let (participant_status_sender, _participant_status_receiver) =
1190      sync_status_channel(16).unwrap();
1191
1192    let (_reader_command_sender, reader_command_receiver) =
1193      mio_channel::sync_channel::<ReaderCommand>(10);
1194
1195    let default_id = EntityId::default();
1196    let reader_guid = GUID::new_with_prefix_and_id(dp.guid_prefix(), default_id);
1197
1198    let reader_ing = ReaderIngredients {
1199      guid: reader_guid,
1200      notification_sender,
1201      status_sender,
1202      topic_name: topic.name(),
1203      topic_cache_handle: topic_cache,
1204      like_stateless: false,
1205      qos_policy: QosPolicies::qos_none(),
1206      data_reader_command_receiver: reader_command_receiver,
1207      data_reader_waker,
1208      poll_event_sender: notification_event_sender,
1209      security_plugins: None,
1210    };
1211
1212    let mut reader = Reader::new(
1213      reader_ing,
1214      Rc::new(UDPSender::new_with_random_port().unwrap()),
1215      crate::polling::new_shared_timer(),
1216      participant_status_sender,
1217    );
1218
1219    // Create the corresponding matching DataReader
1220    let mut datareader = sub
1221      .create_datareader::<RandomData, CDRDeserializerAdapter<RandomData>>(&topic, None)
1222      .unwrap();
1223
1224    let writer_guid = GUID {
1225      prefix: GuidPrefix::new(&[1; 12]),
1226      entity_id: EntityId::create_custom_entity_id(
1227        [1; 3],
1228        EntityKind::WRITER_WITH_KEY_USER_DEFINED,
1229      ),
1230    };
1231    let mr_state = MessageReceiverState {
1232      source_guid_prefix: writer_guid.prefix,
1233      ..Default::default()
1234    };
1235    reader.matched_writer_add(
1236      writer_guid,
1237      EntityId::UNKNOWN,
1238      mr_state.unicast_reply_locator_list.to_vec(),
1239      mr_state.multicast_reply_locator_list.to_vec(),
1240      &QosPolicies::qos_none(),
1241    );
1242
1243    // Reader and datareader ready, feed reader some data
1244    let test_data = RandomData {
1245      a: 10,
1246      b: ":DDD".to_string(),
1247    };
1248
1249    let test_data2 = RandomData {
1250      a: 11,
1251      b: ":)))".to_string(),
1252    };
1253    let data_msg = Data {
1254      reader_id: reader.entity_id(),
1255      writer_id: writer_guid.entity_id,
1256      writer_sn: SequenceNumber::from(1),
1257      serialized_payload: Some(
1258        SerializedPayload {
1259          representation_identifier: RepresentationIdentifier::CDR_LE,
1260          representation_options: [0, 0],
1261          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&test_data).unwrap()),
1262        }
1263        .into(),
1264      ),
1265      ..Data::default()
1266    };
1267
1268    let data_msg2 = Data {
1269      reader_id: reader.entity_id(),
1270      writer_id: writer_guid.entity_id,
1271      writer_sn: SequenceNumber::from(2),
1272      serialized_payload: Some(
1273        SerializedPayload {
1274          representation_identifier: RepresentationIdentifier::CDR_LE,
1275          representation_options: [0, 0],
1276          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&test_data2).unwrap()),
1277        }
1278        .into(),
1279      ),
1280      ..Data::default()
1281    };
1282
1283    let data_flags = DATA_Flags::Endianness | DATA_Flags::Data;
1284
1285    reader.handle_data_msg(data_msg, data_flags, &mr_state);
1286    reader.handle_data_msg(data_msg2, data_flags, &mr_state);
1287
1288    // Test that reading does not consume data samples, i.e. they can be read
1289    // multiple times
1290    {
1291      let result_vec = datareader.read(100, ReadCondition::any()).unwrap();
1292      assert_eq!(result_vec.len(), 2);
1293      let d = result_vec[0]
1294        .value()
1295        .clone()
1296        .value()
1297        .expect("test sample is not a dispose notification");
1298      assert_eq!(&test_data, d);
1299    }
1300    {
1301      let result_vec2 = datareader.read(100, ReadCondition::any()).unwrap();
1302      assert_eq!(result_vec2.len(), 2);
1303      let d2 = result_vec2[1]
1304        .value()
1305        .clone()
1306        .value()
1307        .expect("test sample is not a dispose notification");
1308      assert_eq!(&test_data2, d2);
1309    }
1310    {
1311      let result_vec3 = datareader.read(100, ReadCondition::any()).unwrap();
1312      let d3 = result_vec3[0]
1313        .value()
1314        .clone()
1315        .value()
1316        .expect("test sample is not a dispose notification");
1317      assert_eq!(&test_data, d3);
1318    }
1319
1320    // Test that taking consumes the data samples
1321    let mut result_vec = datareader.take(100, ReadCondition::any()).unwrap();
1322    let datasample2 = result_vec.pop().unwrap();
1323    let datasample1 = result_vec.pop().unwrap();
1324    let data2 = datasample2
1325      .into_value()
1326      .value()
1327      .expect("test data is not a dispose notification");
1328    let data1 = datasample1
1329      .into_value()
1330      .value()
1331      .expect("test data is not a dispose notification");
1332    assert_eq!(test_data2, data2);
1333    assert_eq!(test_data, data1);
1334
1335    let result_vec2 = datareader.take(100, ReadCondition::any());
1336    assert!(result_vec2.is_ok());
1337    assert_eq!(result_vec2.unwrap().len(), 0);
1338  }
1339
1340  #[test]
1341  fn read_and_take_with_instance() {
1342    // Test the methods read_instance and take_instance of the DataReader
1343
1344    let dp = DomainParticipant::new(0).expect("Participant creation failed!");
1345
1346    let mut qos = QosPolicies::qos_none();
1347    qos.history = Some(policy::History::KeepAll); // Just for testing
1348
1349    let sub = dp.create_subscriber(&qos).unwrap();
1350    let topic = dp
1351      .create_topic(
1352        "dr read".to_string(),
1353        "read fn test?".to_string(),
1354        &qos,
1355        TopicKind::WithKey,
1356      )
1357      .unwrap();
1358
1359    let topic_cache =
1360      dp.dds_cache()
1361        .write()
1362        .unwrap()
1363        .add_new_topic(topic.name(), topic.get_type(), &topic.qos());
1364
1365    // Create a Reader
1366    let (notification_sender, _notification_receiver) = mio_channel::sync_channel::<()>(100);
1367    let (_notification_event_source, notification_event_sender) =
1368      mio_source::make_poll_channel().unwrap();
1369    let data_reader_waker = Arc::new(Mutex::new(None));
1370
1371    let (status_sender, _status_receiver) = sync_status_channel::<DataReaderStatus>(4).unwrap();
1372    let (participant_status_sender, _participant_status_receiver) =
1373      sync_status_channel(16).unwrap();
1374
1375    let (_reader_command_sender, reader_command_receiver) =
1376      mio_channel::sync_channel::<ReaderCommand>(10);
1377
1378    let default_id = EntityId::default();
1379    let reader_guid = GUID::new_with_prefix_and_id(dp.guid_prefix(), default_id);
1380
1381    let reader_ing = ReaderIngredients {
1382      guid: reader_guid,
1383      notification_sender,
1384      status_sender,
1385      topic_name: topic.name(),
1386      topic_cache_handle: topic_cache,
1387      like_stateless: false,
1388      qos_policy: QosPolicies::qos_none(),
1389      data_reader_command_receiver: reader_command_receiver,
1390      data_reader_waker,
1391      poll_event_sender: notification_event_sender,
1392      security_plugins: None,
1393    };
1394
1395    let mut reader = Reader::new(
1396      reader_ing,
1397      Rc::new(UDPSender::new_with_random_port().unwrap()),
1398      crate::polling::new_shared_timer(),
1399      participant_status_sender,
1400    );
1401
1402    // Create the corresponding matching DataReader
1403    let mut datareader = sub
1404      .create_datareader::<RandomData, CDRDeserializerAdapter<RandomData>>(&topic, None)
1405      .unwrap();
1406
1407    let writer_guid = GUID {
1408      prefix: GuidPrefix::new(&[1; 12]),
1409      entity_id: EntityId::create_custom_entity_id(
1410        [1; 3],
1411        EntityKind::WRITER_WITH_KEY_USER_DEFINED,
1412      ),
1413    };
1414    let mr_state = MessageReceiverState {
1415      source_guid_prefix: writer_guid.prefix,
1416      ..Default::default()
1417    };
1418    reader.matched_writer_add(
1419      writer_guid,
1420      EntityId::UNKNOWN,
1421      mr_state.unicast_reply_locator_list.to_vec(),
1422      mr_state.multicast_reply_locator_list.to_vec(),
1423      &QosPolicies::qos_none(),
1424    );
1425
1426    // Create 4 data items, 3 of which have the same key
1427    let data_key1 = RandomData {
1428      a: 1,
1429      b: ":D".to_string(),
1430    };
1431    let data_key2_1 = RandomData {
1432      a: 2,
1433      b: ":(".to_string(),
1434    };
1435    let data_key2_2 = RandomData {
1436      a: 2,
1437      b: "??".to_string(),
1438    };
1439    let data_key2_3 = RandomData {
1440      a: 2,
1441      b: "xD".to_string(),
1442    };
1443
1444    let key1 = data_key1.key();
1445    let key2 = data_key2_1.key();
1446
1447    assert!(data_key2_1.key() == data_key2_2.key());
1448    assert!(data_key2_3.key() == key2);
1449
1450    // Create data messages from the data items
1451    // Note that sequence numbering needs to continue as expected
1452    let data_msg = Data {
1453      reader_id: reader.entity_id(),
1454      writer_id: writer_guid.entity_id,
1455      writer_sn: SequenceNumber::from(1),
1456      serialized_payload: Some(
1457        SerializedPayload {
1458          representation_identifier: RepresentationIdentifier::CDR_LE,
1459          representation_options: [0, 0],
1460          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&data_key1).unwrap()),
1461        }
1462        .into(),
1463      ),
1464      ..Data::default()
1465    };
1466    let data_msg2 = Data {
1467      reader_id: reader.entity_id(),
1468      writer_id: writer_guid.entity_id,
1469      writer_sn: SequenceNumber::from(2),
1470      serialized_payload: Some(
1471        SerializedPayload {
1472          representation_identifier: RepresentationIdentifier::CDR_LE,
1473          representation_options: [0, 0],
1474          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&data_key2_1).unwrap()),
1475        }
1476        .into(),
1477      ),
1478      ..Data::default()
1479    };
1480    let data_msg3 = Data {
1481      reader_id: reader.entity_id(),
1482      writer_id: writer_guid.entity_id,
1483      writer_sn: SequenceNumber::from(3),
1484      serialized_payload: Some(
1485        SerializedPayload {
1486          representation_identifier: RepresentationIdentifier::CDR_LE,
1487          representation_options: [0, 0],
1488          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&data_key2_2).unwrap()),
1489        }
1490        .into(),
1491      ),
1492      ..Data::default()
1493    };
1494    let data_msg4 = Data {
1495      reader_id: reader.entity_id(),
1496      writer_id: writer_guid.entity_id,
1497      writer_sn: SequenceNumber::from(4),
1498      serialized_payload: Some(
1499        SerializedPayload {
1500          representation_identifier: RepresentationIdentifier::CDR_LE,
1501          representation_options: [0, 0],
1502          value: Bytes::from(to_vec::<RandomData, LittleEndian>(&data_key2_3).unwrap()),
1503        }
1504        .into(),
1505      ),
1506      ..Data::default()
1507    };
1508
1509    let data_flags = DATA_Flags::Endianness | DATA_Flags::Data;
1510
1511    // Feed the data messages to the reader
1512    reader.handle_data_msg(data_msg, data_flags, &mr_state);
1513    reader.handle_data_msg(data_msg2, data_flags, &mr_state);
1514    reader.handle_data_msg(data_msg3, data_flags, &mr_state);
1515    reader.handle_data_msg(data_msg4, data_flags, &mr_state);
1516
1517    // Check that calling read_instance with different keys and SelectByKey options
1518    // works as expected
1519
1520    info!("calling read with key 1 and this");
1521    let results =
1522      datareader.read_instance(100, ReadCondition::any(), Some(key1), SelectByKey::This);
1523    assert_eq!(
1524      &data_key1,
1525      results.unwrap()[0]
1526        .value()
1527        .clone()
1528        .value()
1529        .expect("test sample is not a dispose notification")
1530    );
1531
1532    info!("calling read with None and this");
1533    // Takes the smallest key, 1 in this case.
1534    let results = datareader.read_instance(100, ReadCondition::any(), None, SelectByKey::This);
1535    assert_eq!(
1536      &data_key1,
1537      results.unwrap()[0]
1538        .value()
1539        .clone()
1540        .value()
1541        .expect("test sample is not a dispose notification")
1542    );
1543
1544    info!("calling read with key 1 and next");
1545    let results =
1546      datareader.read_instance(100, ReadCondition::any(), Some(key1), SelectByKey::Next);
1547    assert_eq!(results.as_ref().unwrap().len(), 3);
1548    assert_eq!(
1549      &data_key2_1,
1550      results.unwrap()[0]
1551        .value()
1552        .clone()
1553        .value()
1554        .expect("test sample is not a dispose notification")
1555    );
1556
1557    // Check that calling take_instance returns all 3 samples with the same key
1558    info!("calling take with key 2 and this");
1559    let results =
1560      datareader.take_instance(100, ReadCondition::any(), Some(key2), SelectByKey::This);
1561    assert_eq!(results.as_ref().unwrap().len(), 3);
1562    let mut vec = results.unwrap();
1563    let d3 = vec.pop().unwrap();
1564    let d3 = d3
1565      .into_value()
1566      .value()
1567      .expect("test data is not a dispose notification");
1568    let d2 = vec.pop().unwrap();
1569    let d2 = d2
1570      .into_value()
1571      .value()
1572      .expect("test data is not a dispose notification");
1573    let d1 = vec.pop().unwrap();
1574    let d1 = d1
1575      .into_value()
1576      .value()
1577      .expect("test data is not a dispose notification");
1578    assert_eq!(data_key2_3, d3);
1579    assert_eq!(data_key2_2, d2);
1580    assert_eq!(data_key2_1, d1);
1581
1582    // Check that calling take_instance again returns nothing because all samples
1583    // have been consumed
1584    info!("calling take with key 2 and this");
1585    let results =
1586      datareader.take_instance(100, ReadCondition::any(), Some(key2), SelectByKey::This);
1587    assert!(results.is_ok());
1588    assert!(results.unwrap().is_empty());
1589  }
1590}