1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use speedy::{Readable, Writable};
5#[allow(unused_imports)]
6use log::{debug, error, info, trace, warn};
7
8use crate::{
9 dds::result::QosError,
10 messages::submessages::elements::parameter::Parameter,
11 serialization::{
12 pl_cdr_adapters::{PlCdrDeserializeError, PlCdrSerializeError},
13 speedy_pl_cdr_helpers::*,
14 },
15 structure::{duration::Duration, endpoint::ReliabilityKind, parameter_id::ParameterId},
16};
17
18pub trait HasQoSPolicy {
23 fn qos(&self) -> QosPolicies;
24}
25
26pub trait MutQosPolicy {
29 fn set_qos(&mut self, new_qos: &QosPolicies) -> Result<(), QosError>;
30}
31
32#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
36pub enum QosPolicyId {
37 Durability, Presentation, Deadline,
42 LatencyBudget, Ownership,
44 Liveliness,
46 TimeBasedFilter, Reliability, DestinationOrder,
54 History, ResourceLimits,
56 Lifespan,
63 Representation, Property, }
67
68#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
70pub struct QosPolicyBuilder {
71 durability: Option<policy::Durability>,
72 presentation: Option<policy::Presentation>,
73 deadline: Option<policy::Deadline>,
74 latency_budget: Option<policy::LatencyBudget>,
75 ownership: Option<policy::Ownership>,
76 liveliness: Option<policy::Liveliness>,
77 time_based_filter: Option<policy::TimeBasedFilter>,
78 reliability: Option<policy::Reliability>,
79 destination_order: Option<policy::DestinationOrder>,
80 history: Option<policy::History>,
81 resource_limits: Option<policy::ResourceLimits>,
82 lifespan: Option<policy::Lifespan>,
83 }
91
92impl QosPolicyBuilder {
93 pub const fn new() -> Self {
94 Self {
96 durability: None,
97 presentation: None,
98 deadline: None,
99 latency_budget: None,
100 ownership: None,
101 liveliness: None,
102 time_based_filter: None,
103 reliability: None,
104 destination_order: None,
105 history: None,
106 resource_limits: None,
107 lifespan: None,
108 }
109 }
110
111 #[must_use]
112 pub const fn durability(mut self, durability: policy::Durability) -> Self {
113 self.durability = Some(durability);
114 self
115 }
116
117 #[must_use]
118 pub const fn presentation(mut self, presentation: policy::Presentation) -> Self {
119 self.presentation = Some(presentation);
120 self
121 }
122
123 #[must_use]
124 pub const fn deadline(mut self, deadline: policy::Deadline) -> Self {
125 self.deadline = Some(deadline);
126 self
127 }
128
129 #[must_use]
130 pub const fn latency_budget(mut self, latency_budget: policy::LatencyBudget) -> Self {
131 self.latency_budget = Some(latency_budget);
132 self
133 }
134
135 #[must_use]
136 pub const fn ownership(mut self, ownership: policy::Ownership) -> Self {
137 self.ownership = Some(ownership);
138 self
139 }
140
141 #[must_use]
142 pub const fn liveliness(mut self, liveliness: policy::Liveliness) -> Self {
143 self.liveliness = Some(liveliness);
144 self
145 }
146
147 #[must_use]
148 pub const fn time_based_filter(mut self, time_based_filter: policy::TimeBasedFilter) -> Self {
149 self.time_based_filter = Some(time_based_filter);
150 self
151 }
152
153 #[must_use]
154 pub const fn reliability(mut self, reliability: policy::Reliability) -> Self {
155 self.reliability = Some(reliability);
156 self
157 }
158
159 #[must_use]
160 pub const fn best_effort(mut self) -> Self {
161 self.reliability = Some(policy::Reliability::BestEffort);
162 self
163 }
164
165 #[must_use]
166 pub const fn reliable(mut self, max_blocking_time: Duration) -> Self {
167 self.reliability = Some(policy::Reliability::Reliable { max_blocking_time });
168 self
169 }
170
171 #[must_use]
172 pub const fn destination_order(mut self, destination_order: policy::DestinationOrder) -> Self {
173 self.destination_order = Some(destination_order);
174 self
175 }
176
177 #[must_use]
178 pub const fn history(mut self, history: policy::History) -> Self {
179 self.history = Some(history);
180 self
181 }
182
183 #[must_use]
184 pub const fn resource_limits(mut self, resource_limits: policy::ResourceLimits) -> Self {
185 self.resource_limits = Some(resource_limits);
186 self
187 }
188
189 #[must_use]
190 pub const fn lifespan(mut self, lifespan: policy::Lifespan) -> Self {
191 self.lifespan = Some(lifespan);
192 self
193 }
194
195 pub const fn build(self) -> QosPolicies {
196 QosPolicies {
197 durability: self.durability,
198 presentation: self.presentation,
199 deadline: self.deadline,
200 latency_budget: self.latency_budget,
201 ownership: self.ownership,
202 liveliness: self.liveliness,
203 time_based_filter: self.time_based_filter,
204 reliability: self.reliability,
205 destination_order: self.destination_order,
206 history: self.history,
207 resource_limits: self.resource_limits,
208 lifespan: self.lifespan,
209 data_representation: None,
213 #[cfg(feature = "security")]
214 property: None,
215 }
216 }
217}
218
219#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
223pub struct QosPolicies {
224 pub(crate) durability: Option<policy::Durability>,
226 pub(crate) presentation: Option<policy::Presentation>,
227 pub(crate) deadline: Option<policy::Deadline>,
228 pub(crate) latency_budget: Option<policy::LatencyBudget>,
229 pub(crate) ownership: Option<policy::Ownership>,
230 pub(crate) liveliness: Option<policy::Liveliness>,
231 pub(crate) time_based_filter: Option<policy::TimeBasedFilter>,
232 pub(crate) reliability: Option<policy::Reliability>,
233 pub(crate) destination_order: Option<policy::DestinationOrder>,
234 pub(crate) history: Option<policy::History>,
235 pub(crate) resource_limits: Option<policy::ResourceLimits>,
236 pub(crate) lifespan: Option<policy::Lifespan>,
237 pub(crate) data_representation: Option<policy::DataRepresentation>,
238 #[cfg(feature = "security")]
239 pub(crate) property: Option<policy::Property>,
240}
241
242impl QosPolicies {
243 pub fn qos_none() -> Self {
246 Self::default()
247 }
248
249 pub fn builder() -> QosPolicyBuilder {
250 QosPolicyBuilder::new()
251 }
252
253 pub const fn durability(&self) -> Option<policy::Durability> {
254 self.durability
255 }
256
257 pub fn is_volatile(&self) -> bool {
258 matches!(self.durability, Some(policy::Durability::Volatile))
259 }
260
261 pub const fn presentation(&self) -> Option<policy::Presentation> {
262 self.presentation
263 }
264
265 pub const fn deadline(&self) -> Option<policy::Deadline> {
266 self.deadline
267 }
268
269 pub const fn latency_budget(&self) -> Option<policy::LatencyBudget> {
270 self.latency_budget
271 }
272
273 pub const fn ownership(&self) -> Option<policy::Ownership> {
274 self.ownership
275 }
276
277 pub const fn liveliness(&self) -> Option<policy::Liveliness> {
278 self.liveliness
279 }
280
281 pub const fn time_based_filter(&self) -> Option<policy::TimeBasedFilter> {
282 self.time_based_filter
283 }
284
285 pub const fn reliability(&self) -> Option<policy::Reliability> {
286 self.reliability
287 }
288
289 pub fn is_reliable(&self) -> bool {
290 matches!(self.reliability, Some(policy::Reliability::Reliable { .. }))
291 }
292
293 pub const fn reliable_max_blocking_time(&self) -> Option<Duration> {
294 if let Some(policy::Reliability::Reliable { max_blocking_time }) = self.reliability {
295 Some(max_blocking_time)
296 } else {
297 None
298 }
299 }
300
301 pub const fn destination_order(&self) -> Option<policy::DestinationOrder> {
302 self.destination_order
303 }
304
305 pub const fn history(&self) -> Option<policy::History> {
306 self.history
307 }
308
309 pub const fn resource_limits(&self) -> Option<policy::ResourceLimits> {
310 self.resource_limits
311 }
312
313 pub const fn lifespan(&self) -> Option<policy::Lifespan> {
314 self.lifespan
315 }
316
317 pub fn data_representation(&self) -> Option<policy::DataRepresentation> {
318 self.data_representation.clone()
319 }
320
321 #[must_use]
328 pub fn with_data_representation(
329 mut self,
330 data_representation: policy::DataRepresentation,
331 ) -> Self {
332 self.data_representation = Some(data_representation);
333 self
334 }
335
336 #[cfg(feature = "security")]
337 pub fn property(&self) -> Option<policy::Property> {
338 self.property.clone()
339 }
340
341 #[must_use]
346 pub fn modify_by(&self, other: &Self) -> Self {
348 Self {
349 durability: other.durability.or(self.durability),
350 presentation: other.presentation.or(self.presentation),
351 deadline: other.deadline.or(self.deadline),
352 latency_budget: other.latency_budget.or(self.latency_budget),
353 ownership: other.ownership.or(self.ownership),
354 liveliness: other.liveliness.or(self.liveliness),
355 time_based_filter: other.time_based_filter.or(self.time_based_filter),
356 reliability: other.reliability.or(self.reliability),
357 destination_order: other.destination_order.or(self.destination_order),
358 history: other.history.or(self.history),
359 resource_limits: other.resource_limits.or(self.resource_limits),
360 lifespan: other.lifespan.or(self.lifespan),
361 data_representation: other
362 .data_representation
363 .clone()
364 .or(self.data_representation.clone()),
365 #[cfg(feature = "security")]
366 property: other.property.clone().or(self.property.clone()),
367 }
368 }
369
370 pub fn compliance_failure_wrt(&self, other: &Self) -> Option<QosPolicyId> {
384 trace!("QoS compatibility check - offered: {self:?} - requested {other:?}");
385 let result = self.compliance_failure_wrt_impl(other);
386 trace!("Result: {result:?}");
387 result
388 }
389
390 fn compliance_failure_wrt_impl(&self, other: &Self) -> Option<QosPolicyId> {
391 {
402 let off = self.durability.unwrap_or(policy::Durability::Volatile);
403 let req = other.durability.unwrap_or(policy::Durability::Volatile);
404 if off < req {
405 return Some(QosPolicyId::Durability);
406 }
407 }
408
409 {
415 let default = policy::Presentation {
416 access_scope: policy::PresentationAccessScope::Instance,
417 coherent_access: false,
418 ordered_access: false,
419 };
420 let off = self.presentation.unwrap_or(default);
421 let req = other.presentation.unwrap_or(default);
422 if (req.coherent_access && !off.coherent_access)
423 || (req.ordered_access && !off.ordered_access)
424 || (req.access_scope > off.access_scope)
425 {
426 return Some(QosPolicyId::Presentation);
427 }
428 }
429
430 {
432 let off = self
433 .deadline
434 .unwrap_or(policy::Deadline(Duration::INFINITE));
435 let req = other
436 .deadline
437 .unwrap_or(policy::Deadline(Duration::INFINITE));
438 if off.0 > req.0 {
439 return Some(QosPolicyId::Deadline);
440 }
441 }
442
443 {
446 let off = self.latency_budget.unwrap_or(policy::LatencyBudget {
447 duration: Duration::ZERO,
448 });
449 let req = other.latency_budget.unwrap_or(policy::LatencyBudget {
450 duration: Duration::ZERO,
451 });
452 if off.duration > req.duration {
453 return Some(QosPolicyId::LatencyBudget);
454 }
455 }
456
457 {
464 let off = self.ownership.unwrap_or(policy::Ownership::Shared);
465 let req = other.ownership.unwrap_or(policy::Ownership::Shared);
466 let same_kind = matches!(
467 (off, req),
468 (policy::Ownership::Shared, policy::Ownership::Shared)
469 | (
470 policy::Ownership::Exclusive { .. },
471 policy::Ownership::Exclusive { .. }
472 )
473 );
474 if !same_kind {
475 return Some(QosPolicyId::Ownership);
476 }
477 }
478
479 {
487 let default = policy::Liveliness::Automatic {
488 lease_duration: Duration::INFINITE,
489 };
490 let off = self.liveliness.unwrap_or(default);
491 let req = other.liveliness.unwrap_or(default);
492 if off < req {
493 return Some(QosPolicyId::Liveliness);
494 }
495 }
496
497 {
503 let off = self.reliability.unwrap_or(policy::Reliability::Reliable {
504 max_blocking_time: Duration::ZERO,
505 });
506 let req = other.reliability.unwrap_or(policy::Reliability::BestEffort);
507 if off < req {
508 return Some(QosPolicyId::Reliability);
509 }
510 }
511
512 {
517 let off = self
518 .destination_order
519 .unwrap_or(policy::DestinationOrder::ByReceptionTimestamp);
520 let req = other
521 .destination_order
522 .unwrap_or(policy::DestinationOrder::ByReceptionTimestamp);
523 if off < req {
524 return Some(QosPolicyId::DestinationOrder);
525 }
526 }
527
528 {
534 let offered =
535 policy::DataRepresentation::offered_representation(self.data_representation.as_ref());
536 let requested =
537 policy::DataRepresentation::accepted_representations(other.data_representation.as_ref());
538 if !requested.contains(&offered) {
539 return Some(QosPolicyId::Representation);
540 }
541 }
542
543 None
545 }
546
547 pub fn to_parameter_list(
549 &self,
550 ctx: speedy::Endianness,
551 ) -> Result<Vec<Parameter>, PlCdrSerializeError> {
552 let mut pl = Vec::with_capacity(8);
553
554 let QosPolicies {
555 durability,
557 presentation,
558 deadline,
559 latency_budget,
560 ownership,
561 liveliness,
562 time_based_filter,
563 reliability,
564 destination_order,
565 history,
566 resource_limits,
567 lifespan,
568 data_representation,
569 #[cfg(feature = "security")]
570 property: _, } = self;
572
573 macro_rules! emit {
574 ($pid:ident, $member:expr, $type:ty) => {
575 pl.push(Parameter::new(ParameterId::$pid, {
576 let m: &$type = $member;
577 m.write_to_vec_with_ctx(ctx)?
578 }))
579 };
580 }
581 macro_rules! emit_option {
582 ($pid:ident, $member:expr, $type:ty) => {
583 if let Some(m) = $member {
584 emit!($pid, m, $type)
585 }
586 };
587 }
588
589 use policy::*;
590
591 emit_option!(PID_DURABILITY, durability, Durability);
592 emit_option!(PID_PRESENTATION, presentation, Presentation);
593 emit_option!(PID_DEADLINE, deadline, Deadline);
594 emit_option!(PID_LATENCY_BUDGET, latency_budget, LatencyBudget);
595
596 match ownership {
598 Some(Ownership::Exclusive { strength }) => {
599 emit!(PID_OWNERSHIP, &OwnershipKind::Exclusive, OwnershipKind);
600 emit!(PID_OWNERSHIP_STRENGTH, strength, i32);
601 }
602 Some(Ownership::Shared) => {
603 emit!(PID_OWNERSHIP, &OwnershipKind::Shared, OwnershipKind);
604 }
605 None => (),
606 }
607 emit_option!(PID_LIVELINESS, liveliness, policy::Liveliness);
609 emit_option!(
610 PID_TIME_BASED_FILTER,
611 time_based_filter,
612 policy::TimeBasedFilter
613 );
614
615 if let Some(rel) = reliability.as_ref() {
616 let reliability_ser = match rel {
617 Reliability::BestEffort => ReliabilitySerialization {
618 reliability_kind: ReliabilityKind::BestEffort,
619 max_blocking_time: Duration::ZERO, },
621 Reliability::Reliable { max_blocking_time } => ReliabilitySerialization {
622 reliability_kind: ReliabilityKind::Reliable,
623 max_blocking_time: *max_blocking_time,
624 },
625 };
626 emit!(PID_RELIABILITY, &reliability_ser, ReliabilitySerialization);
627 }
628
629 emit_option!(
630 PID_DESTINATION_ORDER,
631 destination_order,
632 policy::DestinationOrder
633 );
634
635 if let Some(history) = history.as_ref() {
636 let history_ser = match history {
637 History::KeepLast { depth } => HistorySerialization {
638 kind: HistoryKind::KeepLast,
639 depth: *depth,
640 },
641 History::KeepAll => HistorySerialization {
642 kind: HistoryKind::KeepAll,
643 depth: 0,
644 },
645 };
646 emit!(PID_HISTORY, &history_ser, HistorySerialization);
647 }
648 emit_option!(PID_RESOURCE_LIMITS, resource_limits, policy::ResourceLimits);
649 emit_option!(PID_LIFESPAN, lifespan, policy::Lifespan);
650 emit_option!(
651 PID_DATA_REPRESENTATION,
652 data_representation,
653 policy::DataRepresentation
654 );
655
656 Ok(pl)
657 }
658
659 pub fn from_parameter_list(
660 ctx: speedy::Endianness,
661 pl_map: &BTreeMap<ParameterId, Vec<&Parameter>>,
662 ) -> Result<QosPolicies, PlCdrDeserializeError> {
663 macro_rules! get_option {
664 ($pid:ident) => {
665 get_option_from_pl_map(pl_map, ctx, ParameterId::$pid, "<not_used>")?
666 };
667 }
668
669 let durability: Option<policy::Durability> = get_option!(PID_DURABILITY);
670 let presentation: Option<policy::Presentation> = get_option!(PID_PRESENTATION);
671 let deadline: Option<policy::Deadline> = get_option!(PID_DEADLINE);
672 let latency_budget: Option<policy::LatencyBudget> = get_option!(PID_LATENCY_BUDGET);
673
674 let ownership_kind: Option<OwnershipKind> = get_option!(PID_OWNERSHIP);
676 let ownership_strength: Option<i32> = get_option!(PID_OWNERSHIP_STRENGTH);
677 let ownership = match (ownership_kind, ownership_strength) {
678 (Some(OwnershipKind::Shared), None) => Some(policy::Ownership::Shared),
679 (Some(OwnershipKind::Shared), Some(_strength)) => {
680 warn!("QosPolicies deserializer: Received OwnershipKind::Shared and a strength value.");
681 None
682 }
683 (Some(OwnershipKind::Exclusive), Some(strength)) => {
684 Some(policy::Ownership::Exclusive { strength })
685 }
686 (Some(OwnershipKind::Exclusive), None) => {
687 warn!("QosPolicies deserializer: Received OwnershipKind::Exclusive but no strength value.");
688 None
689 }
690 (None, Some(_strength)) => {
691 warn!(
692 "QosPolicies deserializer: Received ownership strength value, but no kind parameter."
693 );
694 None
695 }
696 (None, None) => None,
697 };
698
699 let reliability_ser: Option<ReliabilitySerialization> = get_option!(PID_RELIABILITY);
700 let reliability = reliability_ser.map(|rs| match rs.reliability_kind {
701 ReliabilityKind::BestEffort => policy::Reliability::BestEffort,
702 ReliabilityKind::Reliable => policy::Reliability::Reliable {
703 max_blocking_time: rs.max_blocking_time,
704 },
705 });
706 let destination_order: Option<policy::DestinationOrder> = get_option!(PID_DESTINATION_ORDER);
707
708 let history_ser: Option<HistorySerialization> = get_option!(PID_HISTORY);
709 let history = history_ser.map(|h| match h.kind {
710 HistoryKind::KeepAll => policy::History::KeepAll,
711 HistoryKind::KeepLast => policy::History::KeepLast { depth: h.depth },
712 });
713
714 let liveliness: Option<policy::Liveliness> = get_option!(PID_LIVELINESS);
715 let time_based_filter: Option<policy::TimeBasedFilter> = get_option!(PID_TIME_BASED_FILTER);
716
717 let resource_limits: Option<policy::ResourceLimits> = get_option!(PID_RESOURCE_LIMITS);
718 let lifespan: Option<policy::Lifespan> = get_option!(PID_LIFESPAN);
719 let data_representation: Option<policy::DataRepresentation> =
720 get_option!(PID_DATA_REPRESENTATION);
721
722 #[cfg(feature = "security")]
723 let property: Option<policy::Property> = None; Ok(QosPolicies {
728 durability,
729 presentation,
730 deadline,
731 latency_budget,
732 ownership,
733 liveliness,
734 time_based_filter,
735 reliability,
736 destination_order,
737 history,
738 resource_limits,
739 lifespan,
740 data_representation,
741 #[cfg(feature = "security")]
742 property,
743 })
744 }
745}
746
747#[derive(Writable, Readable, Clone)]
748enum HistoryKind {
750 KeepLast,
751 KeepAll,
752}
753
754#[derive(Writable, Readable, Clone)]
755struct HistorySerialization {
756 pub kind: HistoryKind,
757 pub depth: i32,
758}
759
760#[derive(Writable, Readable)]
761enum OwnershipKind {
763 Shared,
764 Exclusive,
765}
766
767#[derive(Writable, Readable, Clone)]
768struct ReliabilitySerialization {
769 pub reliability_kind: ReliabilityKind,
770 pub max_blocking_time: Duration,
771}
772
773pub const LENGTH_UNLIMITED: i32 = -1;
778
779pub mod policy {
783 use std::cmp::Ordering;
784
785 use speedy::{Readable, Writable};
786 use serde::{Deserialize, Serialize};
787 #[allow(unused_imports)]
788 use log::{debug, error, info, trace, warn};
789 #[cfg(feature = "security")]
790 use speedy::{Context, IsEof, Reader, Writer};
791
792 use crate::structure::duration::Duration;
793 #[cfg(feature = "security")]
794 use crate::serialization::speedy_pl_cdr_helpers::*;
795
796 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
816 pub struct Lifespan {
817 pub duration: Duration,
818 }
819
820 #[derive(
831 Copy,
832 Clone,
833 Debug,
834 PartialEq,
835 Eq,
836 PartialOrd,
837 Ord,
838 Hash,
839 Readable,
840 Writable,
841 Serialize,
842 Deserialize,
843 )]
844 pub enum Durability {
845 Volatile,
846 TransientLocal,
847 Transient,
848 Persistent,
849 }
850
851 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
853 pub struct Presentation {
854 pub access_scope: PresentationAccessScope,
855 pub coherent_access: bool,
856 pub ordered_access: bool,
857 }
858
859 #[derive(
861 Copy,
862 Clone,
863 Debug,
864 PartialEq,
865 Eq,
866 PartialOrd,
867 Ord,
868 Hash,
869 Readable,
870 Writable,
871 Serialize,
872 Deserialize,
873 )]
874 pub enum PresentationAccessScope {
875 Instance,
876 Topic,
877 Group,
878 }
879
880 #[derive(
882 Copy,
883 Clone,
884 Debug,
885 PartialEq,
886 Eq,
887 Ord,
888 PartialOrd,
889 Hash,
890 Readable,
891 Writable,
892 Serialize,
893 Deserialize,
894 )]
895 pub struct Deadline(pub Duration);
896
897 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
899 pub struct LatencyBudget {
900 pub duration: Duration,
901 }
902
903 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
925 pub enum Ownership {
926 Shared,
927 Exclusive { strength: i32 }, }
929
930 pub type DataRepresentationId = i16;
932
933 pub const XCDR_DATA_REPRESENTATION: DataRepresentationId = 0;
935 pub const XML_DATA_REPRESENTATION: DataRepresentationId = 1;
937 pub const XCDR2_DATA_REPRESENTATION: DataRepresentationId = 2;
939
940 #[derive(Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
950 pub struct DataRepresentation {
951 pub value: Vec<DataRepresentationId>,
952 }
953
954 impl DataRepresentation {
955 pub fn offered_representation(maybe: Option<&DataRepresentation>) -> DataRepresentationId {
959 maybe
960 .and_then(|dr| dr.value.first().copied())
961 .unwrap_or(XCDR_DATA_REPRESENTATION)
962 }
963
964 pub fn accepted_representations(
967 maybe: Option<&DataRepresentation>,
968 ) -> Vec<DataRepresentationId> {
969 match maybe {
970 Some(dr) if !dr.value.is_empty() => dr.value.clone(),
971 _ => vec![XCDR_DATA_REPRESENTATION],
972 }
973 }
974 }
975
976 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
978 pub enum Liveliness {
979 Automatic { lease_duration: Duration },
980 ManualByParticipant { lease_duration: Duration },
981 ManualByTopic { lease_duration: Duration },
982 }
983
984 impl Liveliness {
985 fn kind_num(&self) -> i32 {
986 match self {
987 Self::Automatic { .. } => 0,
988 Self::ManualByParticipant { .. } => 1,
989 Self::ManualByTopic { .. } => 2,
990 }
991 }
992
993 pub fn duration(&self) -> Duration {
994 match self {
995 Self::Automatic { lease_duration }
996 | Self::ManualByParticipant { lease_duration }
997 | Self::ManualByTopic { lease_duration } => *lease_duration,
998 }
999 }
1000 }
1001
1002 impl Ord for Liveliness {
1003 fn cmp(&self, other: &Self) -> Ordering {
1004 other
1007 .kind_num()
1008 .cmp(&other.kind_num())
1009 .then_with(|| self.duration().cmp(&other.duration()).reverse())
1010 }
1011 }
1012
1013 impl PartialOrd for Liveliness {
1014 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1015 Some(self.cmp(other))
1016 }
1017 }
1018
1019 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
1021 pub struct TimeBasedFilter {
1022 pub minimum_separation: Duration,
1023 }
1024
1025 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
1033 pub enum Reliability {
1034 BestEffort,
1035 Reliable { max_blocking_time: Duration },
1036 }
1037
1038 impl Ord for Reliability {
1039 fn cmp(&self, other: &Self) -> Ordering {
1045 match (self, other) {
1046 (Self::BestEffort, Self::BestEffort) | (Self::Reliable { .. }, Self::Reliable { .. }) => {
1047 Ordering::Equal
1048 }
1049 (Self::BestEffort, Self::Reliable { .. }) => Ordering::Less,
1050 (Self::Reliable { .. }, Self::BestEffort) => Ordering::Greater,
1051 }
1052 }
1053 }
1054
1055 impl PartialOrd for Reliability {
1056 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1057 Some(self.cmp(other))
1058 }
1059 }
1060
1061 #[derive(
1063 Copy,
1064 Clone,
1065 Debug,
1066 PartialEq,
1067 Eq,
1068 Ord,
1069 PartialOrd,
1070 Hash,
1071 Readable,
1072 Writable,
1073 Serialize,
1074 Deserialize,
1075 )]
1076 pub enum DestinationOrder {
1077 ByReceptionTimestamp,
1078 BySourceTimeStamp,
1079 }
1080
1081 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
1083 pub enum History {
1084 KeepLast { depth: i32 },
1086 KeepAll,
1087 }
1088
1089 #[derive(Copy, Clone, Debug, PartialEq, Eq, Writable, Readable, Serialize, Deserialize)]
1102 pub struct ResourceLimits {
1103 pub max_samples: i32,
1104 pub max_instances: i32,
1105 pub max_samples_per_instance: i32,
1106 }
1107
1108 #[cfg(feature = "security")]
1109 use crate::security;
1110 #[cfg(feature = "security")]
1114 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
1115 pub struct Property {
1116 pub value: Vec<security::types::Property>,
1117 pub binary_value: Vec<security::types::BinaryProperty>,
1118 }
1119
1120 #[cfg(feature = "security")]
1121 impl<'a, C: Context> Readable<'a, C> for Property {
1122 fn minimum_bytes_needed() -> usize {
1123 4
1124 }
1125
1126 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
1127 let count = reader.read_u32()?;
1128 let mut value = Vec::new();
1129
1130 let mut prev_len = 0;
1131 for _ in 0..count {
1132 read_pad(reader, prev_len, 4)?;
1133 let s: security::types::Property = reader.read_value()?;
1134 prev_len = s.serialized_len();
1135 value.push(s);
1136 }
1137
1138 read_pad(reader, prev_len, 4)?;
1141 let mut binary_value = Vec::new();
1142
1143 match reader.read_u32() {
1144 Ok(count) => {
1145 prev_len = 0;
1146 for _ in 0..count {
1147 read_pad(reader, prev_len, 4)?;
1148 let s: security::types::BinaryProperty = reader.read_value()?;
1149 prev_len = s.serialized_len();
1150 binary_value.push(s);
1151 }
1152 }
1153 Err(e) => {
1154 if e.is_eof() {
1155 debug!("Non-security PropertyQosPolicy");
1157 } else {
1158 return Err(e);
1159 }
1160 }
1161 }
1162
1163 Ok(Property {
1164 value,
1165 binary_value,
1166 })
1167 }
1168 }
1169
1170 #[cfg(feature = "security")]
1175 impl<C: Context> Writable<C> for Property {
1176 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
1177 let propagate_value: Vec<&security::Property> =
1180 self.value.iter().filter(|p| p.propagate).collect();
1181
1182 writer.write_u32(propagate_value.len() as u32)?;
1184
1185 let mut prev_len = 0;
1186 for prop in propagate_value {
1187 write_pad(writer, prev_len, 4)?;
1188 writer.write_value(prop)?;
1189 prev_len = prop.serialized_len();
1190 }
1191
1192 let propagate_bin_value: Vec<&security::BinaryProperty> =
1195 self.binary_value.iter().filter(|p| p.propagate).collect();
1196
1197 write_pad(writer, prev_len, 4)?;
1199 writer.write_u32(propagate_bin_value.len() as u32)?;
1200 let mut prev_len = 0;
1202 for prop in propagate_bin_value {
1203 write_pad(writer, prev_len, 4)?;
1204 writer.write_value(prop)?;
1205 prev_len = prop.serialized_len();
1206 }
1207
1208 Ok(())
1209 }
1210 }
1211
1212 #[derive(Clone, Debug, PartialEq, Eq, Default)]
1219 #[cfg(feature = "security")]
1220 pub struct DataTag {
1221 pub tags: Vec<security::types::Tag>,
1222 }
1223
1224 #[cfg(feature = "security")]
1225 impl<'a, C: Context> Readable<'a, C> for DataTag {
1226 fn minimum_bytes_needed() -> usize {
1227 4
1228 }
1229
1230 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
1231 let count = reader.read_u32()?;
1232 let mut tags = Vec::new();
1233
1234 let mut prev_len = 0;
1235 for _ in 0..count {
1236 read_pad(reader, prev_len, 4)?;
1237 let s: security::types::Tag = reader.read_value()?;
1238 prev_len = s.serialized_len();
1239 tags.push(s);
1240 }
1241 Ok(DataTag { tags })
1242 }
1243 }
1244
1245 #[cfg(feature = "security")]
1250 impl<C: Context> Writable<C> for DataTag {
1251 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
1252 writer.write_u32(self.tags.len() as u32)?;
1253
1254 let mut prev_len = 0;
1255 for tag in &self.tags {
1256 write_pad(writer, prev_len, 4)?;
1257 writer.write_value(tag)?;
1258 prev_len = tag.serialized_len();
1259 }
1260 Ok(())
1261 }
1262 }
1263}