postcard_rpc/header.rs
1//! # Postcard-RPC Header Format
2//!
3//! Postcard-RPC's header is made up of three main parts:
4//!
5//! 1. A one-byte discriminant
6//! 2. A 1-8 byte "Key"
7//! 3. A 1-4 byte "Sequence Number"
8//!
9//! The Postcard-RPC Header is NOT encoded using `postcard`'s wire format.
10//!
11//! ## Discriminant
12//!
13//! The discriminant field is always one byte, and consists of three subfields
14//! in the form `0bNNMM_VVVV`.
15//!
16//! * The two msbits are "key length", where the two N length bits represent
17//! a key length of 2^N. All values are valid.
18//! * The next two msbits are "sequence number length", where the two M length
19//! bits represent a sequence number length of 2^M. Values 00, 01, and 10
20//! are valid.
21//! * The four lsbits are "protocol version", where the four V version bits
22//! represent an unsigned 4-bit number. Currently only 0000 is a valid value.
23//!
24//! ## Key
25//!
26//! The Key consists of an fnv1a hash of the path string and schema of the
27//! contained message. These are calculated using the [`hash` module](crate::hash),
28//! and are natively calculated as an 8-byte hash.
29//!
30//! Keys may be encoded with variable fidelity on the wire, as follows:
31//!
32//! * For 8-byte keys, all key bytes appear in the form `[A, B, C, D, E, F, G, H]`.
33//! * For 4-byte keys, the 8-byte form is compressed as `[A^B, C^D, E^F, G^H]`.
34//! * For 2-byte keys, the 8-byte form is compressed as `[A^B^C^D, E^F^G^H]`.
35//! * For 1-byte keys, the 8-byte form is compressed as `A^B^C^D^E^F^G^H`.
36//!
37//! The length of the Key is determined by the two `NN` bits in the discriminant.
38//!
39//! The length of the key is usually chosen by the **Server**, as the server is
40//! able to calculate the minimum number of bits necessary to avoid collisions.
41//!
42//! When Clients receive a server response, they shall note the Key length used,
43//! and match that for all subsequent messages. When Clients make first connection,
44//! they shall use the 8-byte form by default.
45//!
46//! ## Sequence Number
47//!
48//! The Sequence Number is an unsigned integer used to match request-response pairs,
49//! and disambiguate between multiple in-flight messages.
50//!
51//! Sequence Numbers may be encoded with variable fidelity on the wire, always in
52//! little-endian order, of 1, 2, or 4 bytes.
53//!
54//! The length of the Sequence Number is determined by the two `MM` bits in the
55//! discriminant.
56//!
57//! The length of the key is chosen by the "originator" of the message. For Endpoints
58//! this is the client making the request. For Topics, this is the device sending the
59//! topic message.
60
61use crate::{Key, Key1, Key2, Key4};
62
63//////////////////////////////////////////////////////////////////////////////
64// VARKEY
65//////////////////////////////////////////////////////////////////////////////
66
67/// A variably sized header Key
68///
69/// NOTE: We DO NOT impl Serialize/Deserialize for this type because
70/// we use non-postcard-compatible format (externally tagged) on the wire.
71///
72/// NOTE: VarKey implements `PartialEq` by reducing two VarKeys down to the
73/// smaller of the two forms, and checking whether they match. This allows
74/// a key in 8-byte form to be compared to a key in 1, 2, or 4-byte form
75/// for equality.
76#[derive(Debug, Copy, Clone)]
77pub enum VarKey {
78 /// A one byte key
79 Key1(Key1),
80 /// A two byte key
81 Key2(Key2),
82 /// A four byte key
83 Key4(Key4),
84 /// An eight byte key
85 Key8(Key),
86}
87
88/// We implement PartialEq MANUALLY for VarKey, because keys of different lengths SHOULD compare
89/// as equal.
90impl PartialEq for VarKey {
91 fn eq(&self, other: &Self) -> bool {
92 // figure out the minimum length
93 match (self, other) {
94 // Matching kinds
95 (VarKey::Key1(self_key), VarKey::Key1(other_key)) => self_key.0.eq(&other_key.0),
96 (VarKey::Key2(self_key), VarKey::Key2(other_key)) => self_key.0.eq(&other_key.0),
97 (VarKey::Key4(self_key), VarKey::Key4(other_key)) => self_key.0.eq(&other_key.0),
98 (VarKey::Key8(self_key), VarKey::Key8(other_key)) => {
99 self_key.to_bytes().eq(&other_key.to_bytes())
100 }
101
102 // For the rest of the options, degrade the LARGER key to the SMALLER key, and then
103 // check for equivalence after that.
104 (VarKey::Key1(this), VarKey::Key2(other)) => {
105 let other = Key1::from_key2(*other);
106 this.0.eq(&other.0)
107 }
108 (VarKey::Key1(this), VarKey::Key4(other)) => {
109 let other = Key1::from_key4(*other);
110 this.0.eq(&other.0)
111 }
112 (VarKey::Key1(this), VarKey::Key8(other)) => {
113 let other = Key1::from_key8(*other);
114 this.0.eq(&other.0)
115 }
116 (VarKey::Key2(this), VarKey::Key1(other)) => {
117 let this = Key1::from_key2(*this);
118 this.0.eq(&other.0)
119 }
120 (VarKey::Key2(this), VarKey::Key4(other)) => {
121 let other = Key2::from_key4(*other);
122 this.0.eq(&other.0)
123 }
124 (VarKey::Key2(this), VarKey::Key8(other)) => {
125 let other = Key2::from_key8(*other);
126 this.0.eq(&other.0)
127 }
128 (VarKey::Key4(this), VarKey::Key1(other)) => {
129 let this = Key1::from_key4(*this);
130 this.0.eq(&other.0)
131 }
132 (VarKey::Key4(this), VarKey::Key2(other)) => {
133 let this = Key2::from_key4(*this);
134 this.0.eq(&other.0)
135 }
136 (VarKey::Key4(this), VarKey::Key8(other)) => {
137 let other = Key4::from_key8(*other);
138 this.0.eq(&other.0)
139 }
140 (VarKey::Key8(this), VarKey::Key1(other)) => {
141 let this = Key1::from_key8(*this);
142 this.0.eq(&other.0)
143 }
144 (VarKey::Key8(this), VarKey::Key2(other)) => {
145 let this = Key2::from_key8(*this);
146 this.0.eq(&other.0)
147 }
148 (VarKey::Key8(this), VarKey::Key4(other)) => {
149 let this = Key4::from_key8(*this);
150 this.0.eq(&other.0)
151 }
152 }
153 }
154}
155
156impl VarKey {
157 /// Keys can not be reaised, but instead only shrunk.
158 ///
159 /// This method will shrink to the requested length if that length is
160 /// smaller than the current representation, or if the requested length
161 /// is the same or larger than the current representation, it will be
162 /// kept unchanged
163 pub fn shrink_to(&mut self, kind: VarKeyKind) {
164 match (&self, kind) {
165 (VarKey::Key1(_), _) => {
166 // Nothing to shrink
167 }
168 (VarKey::Key2(key2), VarKeyKind::Key1) => {
169 *self = VarKey::Key1(Key1::from_key2(*key2));
170 }
171 (VarKey::Key2(_), _) => {
172 // We are already as small or smaller than the request
173 }
174 (VarKey::Key4(key4), VarKeyKind::Key1) => {
175 *self = VarKey::Key1(Key1::from_key4(*key4));
176 }
177 (VarKey::Key4(key4), VarKeyKind::Key2) => {
178 *self = VarKey::Key2(Key2::from_key4(*key4));
179 }
180 (VarKey::Key4(_), _) => {
181 // We are already as small or smaller than the request
182 }
183 (VarKey::Key8(key), VarKeyKind::Key1) => {
184 *self = VarKey::Key1(Key1::from_key8(*key));
185 }
186 (VarKey::Key8(key), VarKeyKind::Key2) => {
187 *self = VarKey::Key2(Key2::from_key8(*key));
188 }
189 (VarKey::Key8(key), VarKeyKind::Key4) => {
190 *self = VarKey::Key4(Key4::from_key8(*key));
191 }
192 (VarKey::Key8(_), VarKeyKind::Key8) => {
193 // Nothing to do
194 }
195 }
196 }
197
198 /// The current kind/length of the key
199 pub fn kind(&self) -> VarKeyKind {
200 match self {
201 VarKey::Key1(_) => VarKeyKind::Key1,
202 VarKey::Key2(_) => VarKeyKind::Key2,
203 VarKey::Key4(_) => VarKeyKind::Key4,
204 VarKey::Key8(_) => VarKeyKind::Key8,
205 }
206 }
207}
208
209//////////////////////////////////////////////////////////////////////////////
210// VARKEYKIND
211//////////////////////////////////////////////////////////////////////////////
212
213/// The kind or length of the variably sized header Key
214#[derive(Debug, Copy, Clone, PartialEq, Eq)]
215pub enum VarKeyKind {
216 /// A one byte key
217 Key1,
218 /// A two byte key
219 Key2,
220 /// A four byte key
221 Key4,
222 /// An eight byte key
223 Key8,
224}
225
226//////////////////////////////////////////////////////////////////////////////
227// VARSEQ
228//////////////////////////////////////////////////////////////////////////////
229
230/// A variably sized sequence number
231///
232/// NOTE: We use the standard PartialEq here, as we DO NOT treat sequence
233/// numbers of different lengths as equivalent.
234///
235/// We DO NOT impl Serialize/Deserialize for this type because we use
236/// non-postcard-compatible format (externally tagged)
237#[derive(Debug, Clone, Copy)]
238pub enum VarSeq {
239 /// A one byte sequence number
240 Seq1(u8),
241 /// A two byte sequence number
242 Seq2(u16),
243 /// A four byte sequence number
244 Seq4(u32),
245}
246
247impl From<u8> for VarSeq {
248 fn from(value: u8) -> Self {
249 Self::Seq1(value)
250 }
251}
252
253impl From<u16> for VarSeq {
254 fn from(value: u16) -> Self {
255 Self::Seq2(value)
256 }
257}
258
259impl From<u32> for VarSeq {
260 fn from(value: u32) -> Self {
261 Self::Seq4(value)
262 }
263}
264
265impl Into<u8> for VarSeq {
266 fn into(self) -> u8 {
267 match self {
268 VarSeq::Seq1(v) => v,
269 VarSeq::Seq2(v) => v as u8,
270 VarSeq::Seq4(v) => v as u8,
271 }
272 }
273}
274
275impl Into<u16> for VarSeq {
276 fn into(self) -> u16 {
277 match self {
278 VarSeq::Seq1(v) => v.into(),
279 VarSeq::Seq2(v) => v,
280 VarSeq::Seq4(v) => v as u16,
281 }
282 }
283}
284
285impl Into<u32> for VarSeq {
286 fn into(self) -> u32 {
287 match self {
288 VarSeq::Seq1(v) => v.into(),
289 VarSeq::Seq2(v) => v.into(),
290 VarSeq::Seq4(v) => v,
291 }
292 }
293}
294
295impl PartialEq for VarSeq {
296 fn eq(&self, other: &Self) -> bool {
297 Into::<u32>::into(*self) == Into::<u32>::into(*other)
298 }
299}
300
301impl VarSeq {
302 /// Resize (up or down) to the requested kind.
303 ///
304 /// When increasing size, the number is left-extended, e.g. `0x42u8` becomes
305 /// `0x0000_0042u32` when resizing 1 -> 4.
306 ///
307 /// When decreasing size, the number is truncated, e.g. `0xABCD_EF12u32`
308 /// becomes `0x12u8` when resizing 4 -> 1.
309 pub fn resize(&mut self, kind: VarSeqKind) {
310 match (&self, kind) {
311 (VarSeq::Seq1(_), VarSeqKind::Seq1) => {}
312 (VarSeq::Seq2(_), VarSeqKind::Seq2) => {}
313 (VarSeq::Seq4(_), VarSeqKind::Seq4) => {}
314 (VarSeq::Seq1(s), VarSeqKind::Seq2) => {
315 *self = VarSeq::Seq2((*s).into());
316 }
317 (VarSeq::Seq1(s), VarSeqKind::Seq4) => {
318 *self = VarSeq::Seq4((*s).into());
319 }
320 (VarSeq::Seq2(s), VarSeqKind::Seq1) => {
321 *self = VarSeq::Seq1((*s) as u8);
322 }
323 (VarSeq::Seq2(s), VarSeqKind::Seq4) => {
324 *self = VarSeq::Seq4((*s).into());
325 }
326 (VarSeq::Seq4(s), VarSeqKind::Seq1) => {
327 *self = VarSeq::Seq1((*s) as u8);
328 }
329 (VarSeq::Seq4(s), VarSeqKind::Seq2) => {
330 *self = VarSeq::Seq2((*s) as u16);
331 }
332 }
333 }
334}
335
336//////////////////////////////////////////////////////////////////////////////
337// VARSEQKIND
338//////////////////////////////////////////////////////////////////////////////
339
340/// The Kind or Length of a VarSeq
341#[derive(Debug, Copy, Clone, PartialEq, Eq)]
342pub enum VarSeqKind {
343 /// A one byte sequence number
344 Seq1,
345 /// A two byte sequence number
346 Seq2,
347 /// A four byte sequence number
348 Seq4,
349}
350
351//////////////////////////////////////////////////////////////////////////////
352// VARHEADER
353//////////////////////////////////////////////////////////////////////////////
354
355/// A variably sized message header
356///
357/// NOTE: We use the standard PartialEq here as it will do the correct things.
358///
359/// Sequence numbers must be EXACTLY the same, and keys must be equivalent when
360/// degraded to the smaller of the two.
361///
362/// We DO NOT impl Serialize/Deserialize for this type because we use
363/// non-postcard-compatible format (externally tagged)
364#[derive(Debug, PartialEq, Clone, Copy)]
365pub struct VarHeader {
366 /// The variably sized Key
367 pub key: VarKey,
368 /// The variably sized Sequence Number
369 pub seq_no: VarSeq,
370}
371
372#[allow(clippy::unusual_byte_groupings)]
373impl VarHeader {
374 /// Bits for a key of ONE byte
375 pub const KEY_ONE_BITS: u8 = 0b00_00_0000;
376 /// Bits for a key of TWO bytes
377 pub const KEY_TWO_BITS: u8 = 0b01_00_0000;
378 /// Bits for a key of FOUR bytes
379 pub const KEY_FOUR_BITS: u8 = 0b10_00_0000;
380 /// Bits for a key of EIGHT bytes
381 pub const KEY_EIGHT_BITS: u8 = 0b11_00_0000;
382 /// Mask bits
383 pub const KEY_MASK_BITS: u8 = 0b11_00_0000;
384
385 /// Bits for a sequence number of ONE bytes
386 pub const SEQ_ONE_BITS: u8 = 0b00_00_0000;
387 /// Bits for a sequence number of TWO bytes
388 pub const SEQ_TWO_BITS: u8 = 0b00_01_0000;
389 /// Bits for a sequence number of FOUR bytes
390 pub const SEQ_FOUR_BITS: u8 = 0b00_10_0000;
391 /// Mask bits
392 pub const SEQ_MASK_BITS: u8 = 0b00_11_0000;
393
394 /// Bits for a version number of ZERO
395 pub const VER_ZERO_BITS: u8 = 0b00_00_0000;
396 /// Mask bits
397 pub const VER_MASK_BITS: u8 = 0b00_00_1111;
398
399 /// Encode the header to a Vec of bytes
400 #[cfg(feature = "use-std")]
401 pub fn write_to_vec(&self) -> Vec<u8> {
402 // start with placeholder byte
403 let mut out = vec![0u8; 1];
404 let mut disc_out: u8;
405 match &self.key {
406 VarKey::Key1(k) => {
407 disc_out = Self::KEY_ONE_BITS;
408 out.push(k.0);
409 }
410 VarKey::Key2(k) => {
411 disc_out = Self::KEY_TWO_BITS;
412 out.extend_from_slice(&k.0);
413 }
414 VarKey::Key4(k) => {
415 disc_out = Self::KEY_FOUR_BITS;
416 out.extend_from_slice(&k.0);
417 }
418 VarKey::Key8(k) => {
419 disc_out = Self::KEY_EIGHT_BITS;
420 out.extend_from_slice(&k.to_bytes());
421 }
422 }
423 match &self.seq_no {
424 VarSeq::Seq1(s) => {
425 disc_out |= Self::SEQ_ONE_BITS;
426 out.push(*s);
427 }
428 VarSeq::Seq2(s) => {
429 disc_out |= Self::SEQ_TWO_BITS;
430 out.extend_from_slice(&s.to_le_bytes());
431 }
432 VarSeq::Seq4(s) => {
433 disc_out |= Self::SEQ_FOUR_BITS;
434 out.extend_from_slice(&s.to_le_bytes());
435 }
436 }
437 // push discriminant to the end...
438 out.push(disc_out);
439 // ...and swap-remove the placeholder byte, moving the discriminant to the front
440 out.swap_remove(0);
441 out
442 }
443
444 /// Attempt to write the header to the given slice
445 ///
446 /// If the slice is large enough, a `Some` will be returned with the bytes used
447 /// to encode the header, as well as the remaining unused bytes.
448 ///
449 /// If the slice is not large enough, a `None` will be returned, and some bytes
450 /// of the buffer may have been modified.
451 pub fn write_to_slice<'a>(&self, buf: &'a mut [u8]) -> Option<(&'a mut [u8], &'a mut [u8])> {
452 let (disc_out, mut remain) = buf.split_first_mut()?;
453 let mut used = 1;
454
455 match &self.key {
456 VarKey::Key1(k) => {
457 *disc_out = Self::KEY_ONE_BITS;
458 let (keybs, remain2) = remain.split_first_mut()?;
459 *keybs = k.0;
460 remain = remain2;
461 used += 1;
462 }
463 VarKey::Key2(k) => {
464 *disc_out = Self::KEY_TWO_BITS;
465 let (keybs, remain2) = remain.split_at_mut_checked(2)?;
466 keybs.copy_from_slice(&k.0);
467 remain = remain2;
468 used += 2;
469 }
470 VarKey::Key4(k) => {
471 *disc_out = Self::KEY_FOUR_BITS;
472 let (keybs, remain2) = remain.split_at_mut_checked(4)?;
473 keybs.copy_from_slice(&k.0);
474 remain = remain2;
475 used += 4;
476 }
477 VarKey::Key8(k) => {
478 *disc_out = Self::KEY_EIGHT_BITS;
479 let (keybs, remain2) = remain.split_at_mut_checked(8)?;
480 keybs.copy_from_slice(&k.to_bytes());
481 remain = remain2;
482 used += 8;
483 }
484 }
485 match &self.seq_no {
486 VarSeq::Seq1(s) => {
487 *disc_out |= Self::SEQ_ONE_BITS;
488 let (seqbs, _) = remain.split_first_mut()?;
489 *seqbs = *s;
490 used += 1;
491 }
492 VarSeq::Seq2(s) => {
493 *disc_out |= Self::SEQ_TWO_BITS;
494 let (seqbs, _) = remain.split_at_mut_checked(2)?;
495 seqbs.copy_from_slice(&s.to_le_bytes());
496 used += 2;
497 }
498 VarSeq::Seq4(s) => {
499 *disc_out |= Self::SEQ_FOUR_BITS;
500 let (seqbs, _) = remain.split_at_mut_checked(4)?;
501 seqbs.copy_from_slice(&s.to_le_bytes());
502 used += 4;
503 }
504 }
505 Some(buf.split_at_mut(used))
506 }
507
508 /// Attempt to decode a header from the given bytes.
509 ///
510 /// If a well-formed header was found, a `Some` will be returned with the
511 /// decoded header and unused remaining bytes.
512 ///
513 /// If no well-formed header was found, a `None` will be returned.
514 pub fn take_from_slice(buf: &[u8]) -> Option<(Self, &[u8])> {
515 let (disc, mut remain) = buf.split_first()?;
516
517 // For now, we only trust version zero
518 if (*disc & Self::VER_MASK_BITS) != Self::VER_ZERO_BITS {
519 return None;
520 }
521
522 let key = match (*disc) & Self::KEY_MASK_BITS {
523 Self::KEY_ONE_BITS => {
524 let (keybs, remain2) = remain.split_first()?;
525 remain = remain2;
526 VarKey::Key1(Key1(*keybs))
527 }
528 Self::KEY_TWO_BITS => {
529 let (keybs, remain2) = remain.split_at_checked(2)?;
530 remain = remain2;
531 let mut buf = [0u8; 2];
532 buf.copy_from_slice(keybs);
533 VarKey::Key2(Key2(buf))
534 }
535 Self::KEY_FOUR_BITS => {
536 let (keybs, remain2) = remain.split_at_checked(4)?;
537 remain = remain2;
538 let mut buf = [0u8; 4];
539 buf.copy_from_slice(keybs);
540 VarKey::Key4(Key4(buf))
541 }
542 Self::KEY_EIGHT_BITS => {
543 let (keybs, remain2) = remain.split_at_checked(8)?;
544 remain = remain2;
545 let mut buf = [0u8; 8];
546 buf.copy_from_slice(keybs);
547 VarKey::Key8(unsafe { Key::from_bytes(buf) })
548 }
549 // Impossible: all bits covered
550 _ => unreachable!(),
551 };
552 let seq_no = match (*disc) & Self::SEQ_MASK_BITS {
553 Self::SEQ_ONE_BITS => {
554 let (seqbs, remain3) = remain.split_first()?;
555 remain = remain3;
556 VarSeq::Seq1(*seqbs)
557 }
558 Self::SEQ_TWO_BITS => {
559 let (seqbs, remain3) = remain.split_at_checked(2)?;
560 remain = remain3;
561 let mut buf = [0u8; 2];
562 buf.copy_from_slice(seqbs);
563 VarSeq::Seq2(u16::from_le_bytes(buf))
564 }
565 Self::SEQ_FOUR_BITS => {
566 let (seqbs, remain3) = remain.split_at_checked(4)?;
567 remain = remain3;
568 let mut buf = [0u8; 4];
569 buf.copy_from_slice(seqbs);
570 VarSeq::Seq4(u32::from_le_bytes(buf))
571 }
572 // Possible (could be 0b11), is invalid
573 _ => return None,
574 };
575 Some((Self { key, seq_no }, remain))
576 }
577}
578
579#[cfg(test)]
580mod test {
581 use super::{VarHeader, VarKey, VarSeq};
582 use crate::{Key, Key1, Key2};
583
584 #[test]
585 fn wire_format() {
586 let checks: &[(_, &[u8])] = &[
587 (
588 VarHeader {
589 key: VarKey::Key1(Key1(0)),
590 seq_no: VarSeq::Seq1(0x00),
591 },
592 &[
593 VarHeader::KEY_ONE_BITS | VarHeader::SEQ_ONE_BITS,
594 0x00,
595 0x00,
596 ],
597 ),
598 (
599 VarHeader {
600 key: VarKey::Key1(Key1(1)),
601 seq_no: VarSeq::Seq1(0x02),
602 },
603 &[
604 VarHeader::KEY_ONE_BITS | VarHeader::SEQ_ONE_BITS,
605 0x01,
606 0x02,
607 ],
608 ),
609 (
610 VarHeader {
611 key: VarKey::Key2(Key2([0x42, 0xAF])),
612 seq_no: VarSeq::Seq1(0x02),
613 },
614 &[
615 VarHeader::KEY_TWO_BITS | VarHeader::SEQ_ONE_BITS,
616 0x42,
617 0xAF,
618 0x02,
619 ],
620 ),
621 (
622 VarHeader {
623 key: VarKey::Key1(Key1(1)),
624 seq_no: VarSeq::Seq2(0x42_AF),
625 },
626 &[
627 VarHeader::KEY_ONE_BITS | VarHeader::SEQ_TWO_BITS,
628 0x01,
629 0xAF,
630 0x42,
631 ],
632 ),
633 (
634 VarHeader {
635 key: VarKey::Key8(unsafe {
636 Key::from_bytes([0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89])
637 }),
638 seq_no: VarSeq::Seq4(0x42_AF_AA_BB),
639 },
640 &[
641 VarHeader::KEY_EIGHT_BITS | VarHeader::SEQ_FOUR_BITS,
642 0x12,
643 0x23,
644 0x34,
645 0x45,
646 0x56,
647 0x67,
648 0x78,
649 0x89,
650 0xBB,
651 0xAA,
652 0xAF,
653 0x42,
654 ],
655 ),
656 ];
657
658 let mut buf = [0u8; 1 + 8 + 4];
659
660 for (val, exp) in checks.iter() {
661 let (used, _) = val.write_to_slice(&mut buf).unwrap();
662 assert_eq!(used, *exp);
663 let v = val.write_to_vec();
664 assert_eq!(&v, *exp);
665 let (deser, remain) = VarHeader::take_from_slice(used).unwrap();
666 assert!(remain.is_empty());
667 assert_eq!(val, &deser);
668 }
669 }
670
671 #[test]
672 fn var_seq_equality() {
673 let val32 = 0x12345678;
674 let val16 = 0x9abc;
675 let val8 = 0xde;
676
677 assert_eq!(VarSeq::Seq1(val8), VarSeq::Seq1(val8));
678 assert_eq!(VarSeq::Seq1(val8), VarSeq::Seq2(val8.into()));
679 assert_eq!(VarSeq::Seq1(val8), VarSeq::Seq4(val8.into()));
680 assert_ne!(VarSeq::Seq2(val16), VarSeq::Seq1(val16 as u8));
681 assert_eq!(VarSeq::Seq2(val16), VarSeq::Seq2(val16));
682 assert_eq!(VarSeq::Seq2(val16), VarSeq::Seq4(val16.into()));
683 assert_ne!(VarSeq::Seq4(val32), VarSeq::Seq1(val32 as u8));
684 assert_ne!(VarSeq::Seq4(val32), VarSeq::Seq2(val32 as u16));
685 assert_eq!(VarSeq::Seq4(val32), VarSeq::Seq4(val32));
686 }
687}