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 Property, }
66
67#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
69pub struct QosPolicyBuilder {
70 durability: Option<policy::Durability>,
71 presentation: Option<policy::Presentation>,
72 deadline: Option<policy::Deadline>,
73 latency_budget: Option<policy::LatencyBudget>,
74 ownership: Option<policy::Ownership>,
75 liveliness: Option<policy::Liveliness>,
76 time_based_filter: Option<policy::TimeBasedFilter>,
77 reliability: Option<policy::Reliability>,
78 destination_order: Option<policy::DestinationOrder>,
79 history: Option<policy::History>,
80 resource_limits: Option<policy::ResourceLimits>,
81 lifespan: Option<policy::Lifespan>,
82 #[cfg(feature = "security")]
83 property: Option<policy::Property>,
84}
85
86impl QosPolicyBuilder {
87 pub fn new() -> Self {
88 Self::default()
89 }
90
91 #[must_use]
92 pub const fn durability(mut self, durability: policy::Durability) -> Self {
93 self.durability = Some(durability);
94 self
95 }
96
97 #[must_use]
98 pub const fn presentation(mut self, presentation: policy::Presentation) -> Self {
99 self.presentation = Some(presentation);
100 self
101 }
102
103 #[must_use]
104 pub const fn deadline(mut self, deadline: policy::Deadline) -> Self {
105 self.deadline = Some(deadline);
106 self
107 }
108
109 #[must_use]
110 pub const fn latency_budget(mut self, latency_budget: policy::LatencyBudget) -> Self {
111 self.latency_budget = Some(latency_budget);
112 self
113 }
114
115 #[must_use]
116 pub const fn ownership(mut self, ownership: policy::Ownership) -> Self {
117 self.ownership = Some(ownership);
118 self
119 }
120
121 #[must_use]
122 pub const fn liveliness(mut self, liveliness: policy::Liveliness) -> Self {
123 self.liveliness = Some(liveliness);
124 self
125 }
126
127 #[must_use]
128 pub const fn time_based_filter(mut self, time_based_filter: policy::TimeBasedFilter) -> Self {
129 self.time_based_filter = Some(time_based_filter);
130 self
131 }
132
133 #[must_use]
134 pub const fn reliability(mut self, reliability: policy::Reliability) -> Self {
135 self.reliability = Some(reliability);
136 self
137 }
138
139 #[must_use]
140 pub const fn best_effort(mut self) -> Self {
141 self.reliability = Some(policy::Reliability::BestEffort);
142 self
143 }
144
145 #[must_use]
146 pub const fn reliable(mut self, max_blocking_time: Duration) -> Self {
147 self.reliability = Some(policy::Reliability::Reliable { max_blocking_time });
148 self
149 }
150
151 #[must_use]
152 pub const fn destination_order(mut self, destination_order: policy::DestinationOrder) -> Self {
153 self.destination_order = Some(destination_order);
154 self
155 }
156
157 #[must_use]
158 pub const fn history(mut self, history: policy::History) -> Self {
159 self.history = Some(history);
160 self
161 }
162
163 #[must_use]
164 pub const fn resource_limits(mut self, resource_limits: policy::ResourceLimits) -> Self {
165 self.resource_limits = Some(resource_limits);
166 self
167 }
168
169 #[must_use]
170 pub const fn lifespan(mut self, lifespan: policy::Lifespan) -> Self {
171 self.lifespan = Some(lifespan);
172 self
173 }
174
175 #[cfg(feature = "security")]
176 #[must_use]
177 pub fn property(mut self, property: policy::Property) -> Self {
178 self.property = Some(property);
179 self
180 }
181
182 pub fn build(self) -> QosPolicies {
183 QosPolicies {
184 durability: self.durability,
185 presentation: self.presentation,
186 deadline: self.deadline,
187 latency_budget: self.latency_budget,
188 ownership: self.ownership,
189 liveliness: self.liveliness,
190 time_based_filter: self.time_based_filter,
191 reliability: self.reliability,
192 destination_order: self.destination_order,
193 history: self.history,
194 resource_limits: self.resource_limits,
195 lifespan: self.lifespan,
196 #[cfg(feature = "security")]
197 property: self.property,
198 }
199 }
200}
201
202#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
206pub struct QosPolicies {
207 pub(crate) durability: Option<policy::Durability>,
209 pub(crate) presentation: Option<policy::Presentation>,
210 pub(crate) deadline: Option<policy::Deadline>,
211 pub(crate) latency_budget: Option<policy::LatencyBudget>,
212 pub(crate) ownership: Option<policy::Ownership>,
213 pub(crate) liveliness: Option<policy::Liveliness>,
214 pub(crate) time_based_filter: Option<policy::TimeBasedFilter>,
215 pub(crate) reliability: Option<policy::Reliability>,
216 pub(crate) destination_order: Option<policy::DestinationOrder>,
217 pub(crate) history: Option<policy::History>,
218 pub(crate) resource_limits: Option<policy::ResourceLimits>,
219 pub(crate) lifespan: Option<policy::Lifespan>,
220 #[cfg(feature = "security")]
221 pub(crate) property: Option<policy::Property>,
222}
223
224impl QosPolicies {
225 pub fn qos_none() -> Self {
228 Self::default()
229 }
230
231 pub fn builder() -> QosPolicyBuilder {
232 QosPolicyBuilder::new()
233 }
234
235 pub const fn durability(&self) -> Option<policy::Durability> {
236 self.durability
237 }
238
239 pub fn is_volatile(&self) -> bool {
240 matches!(self.durability, Some(policy::Durability::Volatile))
241 }
242
243 pub const fn presentation(&self) -> Option<policy::Presentation> {
244 self.presentation
245 }
246
247 pub const fn deadline(&self) -> Option<policy::Deadline> {
248 self.deadline
249 }
250
251 pub const fn latency_budget(&self) -> Option<policy::LatencyBudget> {
252 self.latency_budget
253 }
254
255 pub const fn ownership(&self) -> Option<policy::Ownership> {
256 self.ownership
257 }
258
259 pub const fn liveliness(&self) -> Option<policy::Liveliness> {
260 self.liveliness
261 }
262
263 pub const fn time_based_filter(&self) -> Option<policy::TimeBasedFilter> {
264 self.time_based_filter
265 }
266
267 pub const fn reliability(&self) -> Option<policy::Reliability> {
268 self.reliability
269 }
270
271 pub fn is_reliable(&self) -> bool {
272 matches!(self.reliability, Some(policy::Reliability::Reliable { .. }))
273 }
274
275 pub const fn reliable_max_blocking_time(&self) -> Option<Duration> {
276 if let Some(policy::Reliability::Reliable { max_blocking_time }) = self.reliability {
277 Some(max_blocking_time)
278 } else {
279 None
280 }
281 }
282
283 pub const fn destination_order(&self) -> Option<policy::DestinationOrder> {
284 self.destination_order
285 }
286
287 pub const fn history(&self) -> Option<policy::History> {
288 self.history
289 }
290
291 pub const fn resource_limits(&self) -> Option<policy::ResourceLimits> {
292 self.resource_limits
293 }
294
295 pub const fn lifespan(&self) -> Option<policy::Lifespan> {
296 self.lifespan
297 }
298
299 #[cfg(feature = "security")]
300 pub fn property(&self) -> Option<policy::Property> {
301 self.property.clone()
302 }
303
304 #[must_use]
309 pub fn modify_by(&self, other: &Self) -> Self {
310 Self {
311 durability: other.durability.or(self.durability),
312 presentation: other.presentation.or(self.presentation),
313 deadline: other.deadline.or(self.deadline),
314 latency_budget: other.latency_budget.or(self.latency_budget),
315 ownership: other.ownership.or(self.ownership),
316 liveliness: other.liveliness.or(self.liveliness),
317 time_based_filter: other.time_based_filter.or(self.time_based_filter),
318 reliability: other.reliability.or(self.reliability),
319 destination_order: other.destination_order.or(self.destination_order),
320 history: other.history.or(self.history),
321 resource_limits: other.resource_limits.or(self.resource_limits),
322 lifespan: other.lifespan.or(self.lifespan),
323 #[cfg(feature = "security")]
324 property: other.property.clone().or(self.property.clone()),
325 }
326 }
327
328 pub fn compliance_failure_wrt(&self, other: &Self) -> Option<QosPolicyId> {
342 trace!("QoS compatibility check - offered: {self:?} - requested {other:?}");
343 let result = self.compliance_failure_wrt_impl(other);
344 trace!("Result: {result:?}");
345 result
346 }
347
348 fn compliance_failure_wrt_impl(&self, other: &Self) -> Option<QosPolicyId> {
349 if let (Some(off), Some(req)) = (self.durability, other.durability) {
353 if off < req {
354 return Some(QosPolicyId::Durability);
355 }
356 }
357
358 if let (Some(off), Some(req)) = (self.presentation, other.presentation) {
363 if (req.coherent_access && !off.coherent_access)
364 || (req.ordered_access && !off.ordered_access)
365 || (req.access_scope > off.access_scope)
366 {
367 return Some(QosPolicyId::Presentation);
368 }
369 }
370
371 if let (Some(off), Some(req)) = (self.deadline, other.deadline) {
373 if off.0 > req.0 {
374 return Some(QosPolicyId::Deadline);
375 }
376 }
377
378 if let (Some(off), Some(req)) = (self.latency_budget, other.latency_budget) {
381 if off.duration > req.duration {
382 return Some(QosPolicyId::LatencyBudget);
383 }
384 }
385
386 if let (Some(off), Some(req)) = (self.ownership, other.ownership) {
389 if off != req {
390 return Some(QosPolicyId::Ownership);
391 }
392 }
393
394 if let (Some(off), Some(req)) = (self.liveliness, other.liveliness) {
401 if off < req {
402 return Some(QosPolicyId::Liveliness);
403 }
404 }
405
406 if let (Some(off), Some(req)) = (self.reliability, other.reliability) {
410 if off < req {
411 return Some(QosPolicyId::Reliability);
412 }
413 }
414
415 if let (Some(off), Some(req)) = (self.destination_order, other.destination_order) {
419 if off < req {
420 return Some(QosPolicyId::DestinationOrder);
421 }
422 }
423
424 None
426 }
427
428 pub fn to_parameter_list(
430 &self,
431 ctx: speedy::Endianness,
432 ) -> Result<Vec<Parameter>, PlCdrSerializeError> {
433 let mut pl = Vec::with_capacity(8);
434
435 let QosPolicies {
436 durability,
438 presentation,
439 deadline,
440 latency_budget,
441 ownership,
442 liveliness,
443 time_based_filter,
444 reliability,
445 destination_order,
446 history,
447 resource_limits,
448 lifespan,
449 #[cfg(feature = "security")]
450 property: _, } = self;
452
453 macro_rules! emit {
454 ($pid:ident, $member:expr, $type:ty) => {
455 pl.push(Parameter::new(ParameterId::$pid, {
456 let m: &$type = $member;
457 m.write_to_vec_with_ctx(ctx)?
458 }))
459 };
460 }
461 macro_rules! emit_option {
462 ($pid:ident, $member:expr, $type:ty) => {
463 if let Some(m) = $member {
464 emit!($pid, m, $type)
465 }
466 };
467 }
468
469 use policy::*;
470
471 emit_option!(PID_DURABILITY, durability, Durability);
472 emit_option!(PID_PRESENTATION, presentation, Presentation);
473 emit_option!(PID_DEADLINE, deadline, Deadline);
474 emit_option!(PID_LATENCY_BUDGET, latency_budget, LatencyBudget);
475
476 match ownership {
478 Some(Ownership::Exclusive { strength }) => {
479 emit!(PID_OWNERSHIP, &OwnershipKind::Exclusive, OwnershipKind);
480 emit!(PID_OWNERSHIP_STRENGTH, strength, i32);
481 }
482 Some(Ownership::Shared) => {
483 emit!(PID_OWNERSHIP, &OwnershipKind::Shared, OwnershipKind);
484 }
485 None => (),
486 }
487 emit_option!(PID_LIVELINESS, liveliness, policy::Liveliness);
489 emit_option!(
490 PID_TIME_BASED_FILTER,
491 time_based_filter,
492 policy::TimeBasedFilter
493 );
494
495 if let Some(rel) = reliability.as_ref() {
496 let reliability_ser = match rel {
497 Reliability::BestEffort => ReliabilitySerialization {
498 reliability_kind: ReliabilityKind::BestEffort,
499 max_blocking_time: Duration::ZERO, },
501 Reliability::Reliable { max_blocking_time } => ReliabilitySerialization {
502 reliability_kind: ReliabilityKind::Reliable,
503 max_blocking_time: *max_blocking_time,
504 },
505 };
506 emit!(PID_RELIABILITY, &reliability_ser, ReliabilitySerialization);
507 }
508
509 emit_option!(
510 PID_DESTINATION_ORDER,
511 destination_order,
512 policy::DestinationOrder
513 );
514
515 if let Some(history) = history.as_ref() {
516 let history_ser = match history {
517 History::KeepLast { depth } => HistorySerialization {
518 kind: HistoryKind::KeepLast,
519 depth: *depth,
520 },
521 History::KeepAll => HistorySerialization {
522 kind: HistoryKind::KeepAll,
523 depth: 0,
524 },
525 };
526 emit!(PID_HISTORY, &history_ser, HistorySerialization);
527 }
528 emit_option!(PID_RESOURCE_LIMITS, resource_limits, policy::ResourceLimits);
529 emit_option!(PID_LIFESPAN, lifespan, policy::Lifespan);
530
531 Ok(pl)
532 }
533
534 pub fn from_parameter_list(
535 ctx: speedy::Endianness,
536 pl_map: &BTreeMap<ParameterId, Vec<&Parameter>>,
537 ) -> Result<QosPolicies, PlCdrDeserializeError> {
538 macro_rules! get_option {
539 ($pid:ident) => {
540 get_option_from_pl_map(pl_map, ctx, ParameterId::$pid, "<not_used>")?
541 };
542 }
543
544 let durability: Option<policy::Durability> = get_option!(PID_DURABILITY);
545 let presentation: Option<policy::Presentation> = get_option!(PID_PRESENTATION);
546 let deadline: Option<policy::Deadline> = get_option!(PID_DEADLINE);
547 let latency_budget: Option<policy::LatencyBudget> = get_option!(PID_LATENCY_BUDGET);
548
549 let ownership_kind: Option<OwnershipKind> = get_option!(PID_OWNERSHIP);
551 let ownership_strength: Option<i32> = get_option!(PID_OWNERSHIP_STRENGTH);
552 let ownership = match (ownership_kind, ownership_strength) {
553 (Some(OwnershipKind::Shared), None) => Some(policy::Ownership::Shared),
554 (Some(OwnershipKind::Shared), Some(_strength)) => {
555 warn!("QosPolicies deserializer: Received OwnershipKind::Shared and a strength value.");
556 None
557 }
558 (Some(OwnershipKind::Exclusive), Some(strength)) => {
559 Some(policy::Ownership::Exclusive { strength })
560 }
561 (Some(OwnershipKind::Exclusive), None) => {
562 warn!("QosPolicies deserializer: Received OwnershipKind::Exclusive but no strength value.");
563 None
564 }
565 (None, Some(_strength)) => {
566 warn!(
567 "QosPolicies deserializer: Received ownership strength value, but no kind parameter."
568 );
569 None
570 }
571 (None, None) => None,
572 };
573
574 let reliability_ser: Option<ReliabilitySerialization> = get_option!(PID_RELIABILITY);
575 let reliability = reliability_ser.map(|rs| match rs.reliability_kind {
576 ReliabilityKind::BestEffort => policy::Reliability::BestEffort,
577 ReliabilityKind::Reliable => policy::Reliability::Reliable {
578 max_blocking_time: rs.max_blocking_time,
579 },
580 });
581 let destination_order: Option<policy::DestinationOrder> = get_option!(PID_DESTINATION_ORDER);
582
583 let history_ser: Option<HistorySerialization> = get_option!(PID_HISTORY);
584 let history = history_ser.map(|h| match h.kind {
585 HistoryKind::KeepAll => policy::History::KeepAll,
586 HistoryKind::KeepLast => policy::History::KeepLast { depth: h.depth },
587 });
588
589 let liveliness: Option<policy::Liveliness> = get_option!(PID_LIVELINESS);
590 let time_based_filter: Option<policy::TimeBasedFilter> = get_option!(PID_TIME_BASED_FILTER);
591
592 let resource_limits: Option<policy::ResourceLimits> = get_option!(PID_RESOURCE_LIMITS);
593 let lifespan: Option<policy::Lifespan> = get_option!(PID_LIFESPAN);
594
595 #[cfg(feature = "security")]
596 let property: Option<policy::Property> = None; Ok(QosPolicies {
601 durability,
602 presentation,
603 deadline,
604 latency_budget,
605 ownership,
606 liveliness,
607 time_based_filter,
608 reliability,
609 destination_order,
610 history,
611 resource_limits,
612 lifespan,
613 #[cfg(feature = "security")]
614 property,
615 })
616 }
617}
618
619#[derive(Writable, Readable, Clone)]
620enum HistoryKind {
622 KeepLast,
623 KeepAll,
624}
625
626#[derive(Writable, Readable, Clone)]
627struct HistorySerialization {
628 pub kind: HistoryKind,
629 pub depth: i32,
630}
631
632#[derive(Writable, Readable)]
633enum OwnershipKind {
635 Shared,
636 Exclusive,
637}
638
639#[derive(Writable, Readable, Clone)]
640struct ReliabilitySerialization {
641 pub reliability_kind: ReliabilityKind,
642 pub max_blocking_time: Duration,
643}
644
645pub const LENGTH_UNLIMITED: i32 = -1;
650
651pub mod policy {
655 use std::cmp::Ordering;
656
657 use speedy::{Readable, Writable};
658 use serde::{Deserialize, Serialize};
659 #[allow(unused_imports)]
660 use log::{debug, error, info, trace, warn};
661 #[cfg(feature = "security")]
662 use speedy::{Context, IsEof, Reader, Writer};
663
664 use crate::structure::duration::Duration;
665 #[cfg(feature = "security")]
666 use crate::serialization::speedy_pl_cdr_helpers::*;
667
668 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
688 pub struct Lifespan {
689 pub duration: Duration,
690 }
691
692 #[derive(
703 Copy,
704 Clone,
705 Debug,
706 PartialEq,
707 Eq,
708 PartialOrd,
709 Ord,
710 Hash,
711 Readable,
712 Writable,
713 Serialize,
714 Deserialize,
715 )]
716 pub enum Durability {
717 Volatile,
718 TransientLocal,
719 Transient,
720 Persistent,
721 }
722
723 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
725 pub struct Presentation {
726 pub access_scope: PresentationAccessScope,
727 pub coherent_access: bool,
728 pub ordered_access: bool,
729 }
730
731 #[derive(
733 Copy,
734 Clone,
735 Debug,
736 PartialEq,
737 Eq,
738 PartialOrd,
739 Ord,
740 Hash,
741 Readable,
742 Writable,
743 Serialize,
744 Deserialize,
745 )]
746 pub enum PresentationAccessScope {
747 Instance,
748 Topic,
749 Group,
750 }
751
752 #[derive(
754 Copy,
755 Clone,
756 Debug,
757 PartialEq,
758 Eq,
759 Ord,
760 PartialOrd,
761 Hash,
762 Readable,
763 Writable,
764 Serialize,
765 Deserialize,
766 )]
767 pub struct Deadline(pub Duration);
768
769 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
771 pub struct LatencyBudget {
772 pub duration: Duration,
773 }
774
775 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
777 pub enum Ownership {
778 Shared,
779 Exclusive { strength: i32 }, }
781
782 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
784 pub enum Liveliness {
785 Automatic { lease_duration: Duration },
786 ManualByParticipant { lease_duration: Duration },
787 ManualByTopic { lease_duration: Duration },
788 }
789
790 impl Liveliness {
791 fn kind_num(&self) -> i32 {
792 match self {
793 Self::Automatic { .. } => 0,
794 Self::ManualByParticipant { .. } => 1,
795 Self::ManualByTopic { .. } => 2,
796 }
797 }
798
799 pub fn duration(&self) -> Duration {
800 match self {
801 Self::Automatic { lease_duration }
802 | Self::ManualByParticipant { lease_duration }
803 | Self::ManualByTopic { lease_duration } => *lease_duration,
804 }
805 }
806 }
807
808 impl Ord for Liveliness {
809 fn cmp(&self, other: &Self) -> Ordering {
810 other
813 .kind_num()
814 .cmp(&other.kind_num())
815 .then_with(|| self.duration().cmp(&other.duration()).reverse())
816 }
817 }
818
819 impl PartialOrd for Liveliness {
820 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
821 Some(self.cmp(other))
822 }
823 }
824
825 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Readable, Writable, Serialize, Deserialize)]
827 pub struct TimeBasedFilter {
828 pub minimum_separation: Duration,
829 }
830
831 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
839 pub enum Reliability {
840 BestEffort,
841 Reliable { max_blocking_time: Duration },
842 }
843
844 impl Ord for Reliability {
845 fn cmp(&self, other: &Self) -> Ordering {
851 match (self, other) {
852 (Self::BestEffort, Self::BestEffort) | (Self::Reliable { .. }, Self::Reliable { .. }) => {
853 Ordering::Equal
854 }
855 (Self::BestEffort, Self::Reliable { .. }) => Ordering::Less,
856 (Self::Reliable { .. }, Self::BestEffort) => Ordering::Greater,
857 }
858 }
859 }
860
861 impl PartialOrd for Reliability {
862 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
863 Some(self.cmp(other))
864 }
865 }
866
867 #[derive(
869 Copy,
870 Clone,
871 Debug,
872 PartialEq,
873 Eq,
874 Ord,
875 PartialOrd,
876 Hash,
877 Readable,
878 Writable,
879 Serialize,
880 Deserialize,
881 )]
882 pub enum DestinationOrder {
883 ByReceptionTimestamp,
884 BySourceTimeStamp,
885 }
886
887 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
889 pub enum History {
890 KeepLast { depth: i32 },
892 KeepAll,
893 }
894
895 #[derive(Copy, Clone, Debug, PartialEq, Eq, Writable, Readable, Serialize, Deserialize)]
908 pub struct ResourceLimits {
909 pub max_samples: i32,
910 pub max_instances: i32,
911 pub max_samples_per_instance: i32,
912 }
913
914 #[cfg(feature = "security")]
915 use crate::security;
916 #[cfg(feature = "security")]
920 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
921 pub struct Property {
922 pub value: Vec<security::types::Property>,
923 pub binary_value: Vec<security::types::BinaryProperty>,
924 }
925
926 #[cfg(feature = "security")]
927 impl<'a, C: Context> Readable<'a, C> for Property {
928 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
929 let count = reader.read_u32()?;
930 let mut value = Vec::new();
931
932 let mut prev_len = 0;
933 for _ in 0..count {
934 read_pad(reader, prev_len, 4)?;
935 let s: security::types::Property = reader.read_value()?;
936 prev_len = s.serialized_len();
937 value.push(s);
938 }
939
940 read_pad(reader, prev_len, 4)?;
943 let mut binary_value = Vec::new();
944
945 match reader.read_u32() {
946 Ok(count) => {
947 prev_len = 0;
948 for _ in 0..count {
949 read_pad(reader, prev_len, 4)?;
950 let s: security::types::BinaryProperty = reader.read_value()?;
951 prev_len = s.serialized_len();
952 binary_value.push(s);
953 }
954 }
955 Err(e) => {
956 if e.is_eof() {
957 debug!("Non-security PropertyQosPolicy");
959 } else {
960 return Err(e);
961 }
962 }
963 }
964
965 Ok(Property {
966 value,
967 binary_value,
968 })
969 }
970 }
971
972 #[cfg(feature = "security")]
977 impl<C: Context> Writable<C> for Property {
978 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
979 let propagate_value: Vec<&security::Property> =
982 self.value.iter().filter(|p| p.propagate).collect();
983
984 writer.write_u32(propagate_value.len() as u32)?;
986
987 let mut prev_len = 0;
988 for prop in propagate_value {
989 write_pad(writer, prev_len, 4)?;
990 writer.write_value(prop)?;
991 prev_len = prop.serialized_len();
992 }
993
994 let propagate_bin_value: Vec<&security::BinaryProperty> =
997 self.binary_value.iter().filter(|p| p.propagate).collect();
998
999 write_pad(writer, prev_len, 4)?;
1001 writer.write_u32(propagate_bin_value.len() as u32)?;
1002 let mut prev_len = 0;
1004 for prop in propagate_bin_value {
1005 write_pad(writer, prev_len, 4)?;
1006 writer.write_value(prop)?;
1007 prev_len = prop.serialized_len();
1008 }
1009
1010 Ok(())
1011 }
1012 }
1013
1014 #[derive(Clone, Debug, PartialEq, Eq, Default)]
1021 #[cfg(feature = "security")]
1022 pub struct DataTag {
1023 pub tags: Vec<security::types::Tag>,
1024 }
1025
1026 #[cfg(feature = "security")]
1027 impl<'a, C: Context> Readable<'a, C> for DataTag {
1028 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
1029 let count = reader.read_u32()?;
1030 let mut tags = Vec::new();
1031
1032 let mut prev_len = 0;
1033 for _ in 0..count {
1034 read_pad(reader, prev_len, 4)?;
1035 let s: security::types::Tag = reader.read_value()?;
1036 prev_len = s.serialized_len();
1037 tags.push(s);
1038 }
1039 Ok(DataTag { tags })
1040 }
1041 }
1042
1043 #[cfg(feature = "security")]
1048 impl<C: Context> Writable<C> for DataTag {
1049 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
1050 writer.write_u32(self.tags.len() as u32)?;
1051
1052 let mut prev_len = 0;
1053 for tag in &self.tags {
1054 write_pad(writer, prev_len, 4)?;
1055 writer.write_value(tag)?;
1056 prev_len = tag.serialized_len();
1057 }
1058 Ok(())
1059 }
1060 }
1061}