1use std::fmt;
7use std::net::{Ipv4Addr, Ipv6Addr};
8use thiserror::Error;
9
10#[derive(Debug, Error, Clone, PartialEq, Eq)]
12pub enum FieldError {
13 #[error("buffer too short: need {need} bytes at offset {offset}, have {have}")]
14 BufferTooShort {
15 offset: usize,
16 need: usize,
17 have: usize,
18 },
19
20 #[error("invalid MAC address format: {0}")]
21 InvalidMac(String),
22
23 #[error("invalid IP address format: {0}")]
24 InvalidIp(String),
25
26 #[error("field type mismatch: expected {expected}, got {got}")]
27 TypeMismatch {
28 expected: &'static str,
29 got: &'static str,
30 },
31
32 #[error("field not found: {0}")]
33 FieldNotFound(String),
34
35 #[error("invalid field value: {0}")]
36 InvalidValue(String),
37}
38
39#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
41pub struct MacAddress(pub [u8; 6]);
42
43impl MacAddress {
44 pub const ZERO: Self = Self([0x00; 6]);
45 pub const BROADCAST: Self = Self([0xff; 6]);
46 pub const IPV4_MULTICAST_PREFIX: [u8; 3] = [0x01, 0x00, 0x5e];
48 pub const IPV6_MULTICAST_PREFIX: [u8; 2] = [0x33, 0x33];
50
51 #[inline]
52 pub const fn new(bytes: [u8; 6]) -> Self {
53 Self(bytes)
54 }
55
56 #[inline]
57 pub const fn as_bytes(&self) -> &[u8; 6] {
58 &self.0
59 }
60
61 #[inline]
62 pub const fn to_bytes(self) -> [u8; 6] {
63 self.0
64 }
65
66 #[inline]
67 pub fn is_broadcast(&self) -> bool {
68 self.0 == [0xff; 6]
69 }
70
71 #[inline]
72 pub fn is_multicast(&self) -> bool {
73 self.0[0] & 0x01 != 0
74 }
75
76 #[inline]
77 pub fn is_unicast(&self) -> bool {
78 !self.is_multicast()
79 }
80
81 #[inline]
82 pub fn is_local(&self) -> bool {
83 self.0[0] & 0x02 != 0
84 }
85
86 #[inline]
87 pub fn is_zero(&self) -> bool {
88 self.0 == [0x00; 6]
89 }
90
91 #[inline]
93 pub fn is_ipv4_multicast(&self) -> bool {
94 self.0[0] == 0x01 && self.0[1] == 0x00 && self.0[2] == 0x5e
95 }
96
97 #[inline]
99 pub fn is_ipv6_multicast(&self) -> bool {
100 self.0[0] == 0x33 && self.0[1] == 0x33
101 }
102
103 pub fn from_ipv4_multicast(ip: Ipv4Addr) -> Self {
105 let octets = ip.octets();
106 Self([0x01, 0x00, 0x5e, octets[1] & 0x7f, octets[2], octets[3]])
107 }
108
109 pub fn from_ipv6_multicast(ip: Ipv6Addr) -> Self {
111 let octets = ip.octets();
112 Self([0x33, 0x33, octets[12], octets[13], octets[14], octets[15]])
113 }
114
115 pub fn parse(s: &str) -> Result<Self, FieldError> {
117 let s = s.trim();
118 let parts: Vec<&str> = if s.contains(':') {
119 s.split(':').collect()
120 } else if s.contains('-') {
121 s.split('-').collect()
122 } else if s.len() == 12 {
123 return Self::parse_bare_hex(s);
125 } else {
126 return Err(FieldError::InvalidMac(s.to_string()));
127 };
128
129 if parts.len() != 6 {
130 return Err(FieldError::InvalidMac(s.to_string()));
131 }
132
133 let mut bytes = [0u8; 6];
134 for (i, part) in parts.iter().enumerate() {
135 bytes[i] =
136 u8::from_str_radix(part, 16).map_err(|_| FieldError::InvalidMac(s.to_string()))?;
137 }
138 Ok(Self(bytes))
139 }
140
141 fn parse_bare_hex(s: &str) -> Result<Self, FieldError> {
142 if s.len() != 12 {
143 return Err(FieldError::InvalidMac(s.to_string()));
144 }
145 let mut bytes = [0u8; 6];
146 for i in 0..6 {
147 bytes[i] = u8::from_str_radix(&s[i * 2..i * 2 + 2], 16)
148 .map_err(|_| FieldError::InvalidMac(s.to_string()))?;
149 }
150 Ok(Self(bytes))
151 }
152
153 #[inline]
154 pub fn read_from(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
155 <Self as Field>::read(buf, offset)
156 }
157
158 #[inline]
159 pub fn write_to(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
160 <Self as Field>::write(self, buf, offset)
161 }
162}
163
164impl fmt::Debug for MacAddress {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 write!(f, "MacAddress({})", self)
167 }
168}
169
170impl fmt::Display for MacAddress {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 write!(
173 f,
174 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
175 self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]
176 )
177 }
178}
179
180impl From<[u8; 6]> for MacAddress {
181 fn from(bytes: [u8; 6]) -> Self {
182 Self(bytes)
183 }
184}
185
186impl From<MacAddress> for [u8; 6] {
187 fn from(mac: MacAddress) -> Self {
188 mac.0
189 }
190}
191
192impl std::str::FromStr for MacAddress {
193 type Err = FieldError;
194 fn from_str(s: &str) -> Result<Self, Self::Err> {
195 Self::parse(s)
196 }
197}
198
199pub trait Field: Sized {
201 const SIZE: Option<usize>;
203
204 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError>;
206
207 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError>;
209}
210
211impl Field for u8 {
216 const SIZE: Option<usize> = Some(1);
217
218 #[inline]
219 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
220 buf.get(offset)
221 .copied()
222 .ok_or_else(|| FieldError::BufferTooShort {
223 offset,
224 need: 1,
225 have: buf.len(),
226 })
227 }
228
229 #[inline]
230 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
231 let len = buf.len();
232 *buf.get_mut(offset).ok_or(FieldError::BufferTooShort {
233 offset,
234 need: 1,
235 have: len,
236 })? = *self;
237 Ok(())
238 }
239}
240
241impl Field for u16 {
242 const SIZE: Option<usize> = Some(2);
243
244 #[inline]
245 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
246 if buf.len() < offset + 2 {
247 return Err(FieldError::BufferTooShort {
248 offset,
249 need: 2,
250 have: buf.len(),
251 });
252 }
253 Ok(u16::from_be_bytes([buf[offset], buf[offset + 1]]))
254 }
255
256 #[inline]
257 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
258 if buf.len() < offset + 2 {
259 return Err(FieldError::BufferTooShort {
260 offset,
261 need: 2,
262 have: buf.len(),
263 });
264 }
265 let bytes = self.to_be_bytes();
266 buf[offset] = bytes[0];
267 buf[offset + 1] = bytes[1];
268 Ok(())
269 }
270}
271
272impl Field for u32 {
273 const SIZE: Option<usize> = Some(4);
274
275 #[inline]
276 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
277 if buf.len() < offset + 4 {
278 return Err(FieldError::BufferTooShort {
279 offset,
280 need: 4,
281 have: buf.len(),
282 });
283 }
284 Ok(u32::from_be_bytes([
285 buf[offset],
286 buf[offset + 1],
287 buf[offset + 2],
288 buf[offset + 3],
289 ]))
290 }
291
292 #[inline]
293 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
294 if buf.len() < offset + 4 {
295 return Err(FieldError::BufferTooShort {
296 offset,
297 need: 4,
298 have: buf.len(),
299 });
300 }
301 buf[offset..offset + 4].copy_from_slice(&self.to_be_bytes());
302 Ok(())
303 }
304}
305
306impl Field for u64 {
307 const SIZE: Option<usize> = Some(8);
308
309 #[inline]
310 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
311 if buf.len() < offset + 8 {
312 return Err(FieldError::BufferTooShort {
313 offset,
314 need: 8,
315 have: buf.len(),
316 });
317 }
318 let mut bytes = [0u8; 8];
319 bytes.copy_from_slice(&buf[offset..offset + 8]);
320 Ok(u64::from_be_bytes(bytes))
321 }
322
323 #[inline]
324 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
325 if buf.len() < offset + 8 {
326 return Err(FieldError::BufferTooShort {
327 offset,
328 need: 8,
329 have: buf.len(),
330 });
331 }
332 buf[offset..offset + 8].copy_from_slice(&self.to_be_bytes());
333 Ok(())
334 }
335}
336
337impl Field for MacAddress {
338 const SIZE: Option<usize> = Some(6);
339
340 #[inline]
341 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
342 if buf.len() < offset + 6 {
343 return Err(FieldError::BufferTooShort {
344 offset,
345 need: 6,
346 have: buf.len(),
347 });
348 }
349 Ok(Self([
350 buf[offset],
351 buf[offset + 1],
352 buf[offset + 2],
353 buf[offset + 3],
354 buf[offset + 4],
355 buf[offset + 5],
356 ]))
357 }
358
359 #[inline]
360 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
361 if buf.len() < offset + 6 {
362 return Err(FieldError::BufferTooShort {
363 offset,
364 need: 6,
365 have: buf.len(),
366 });
367 }
368 buf[offset..offset + 6].copy_from_slice(&self.0);
369 Ok(())
370 }
371}
372
373impl Field for Ipv4Addr {
374 const SIZE: Option<usize> = Some(4);
375
376 #[inline]
377 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
378 if buf.len() < offset + 4 {
379 return Err(FieldError::BufferTooShort {
380 offset,
381 need: 4,
382 have: buf.len(),
383 });
384 }
385 Ok(Ipv4Addr::new(
386 buf[offset],
387 buf[offset + 1],
388 buf[offset + 2],
389 buf[offset + 3],
390 ))
391 }
392
393 #[inline]
394 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
395 if buf.len() < offset + 4 {
396 return Err(FieldError::BufferTooShort {
397 offset,
398 need: 4,
399 have: buf.len(),
400 });
401 }
402 buf[offset..offset + 4].copy_from_slice(&self.octets());
403 Ok(())
404 }
405}
406
407impl Field for Ipv6Addr {
408 const SIZE: Option<usize> = Some(16);
409
410 #[inline]
411 fn read(buf: &[u8], offset: usize) -> Result<Self, FieldError> {
412 if buf.len() < offset + 16 {
413 return Err(FieldError::BufferTooShort {
414 offset,
415 need: 16,
416 have: buf.len(),
417 });
418 }
419 let mut arr = [0u8; 16];
420 arr.copy_from_slice(&buf[offset..offset + 16]);
421 Ok(Ipv6Addr::from(arr))
422 }
423
424 #[inline]
425 fn write(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
426 if buf.len() < offset + 16 {
427 return Err(FieldError::BufferTooShort {
428 offset,
429 need: 16,
430 have: buf.len(),
431 });
432 }
433 buf[offset..offset + 16].copy_from_slice(&self.octets());
434 Ok(())
435 }
436}
437
438#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
444pub struct BytesField(pub Vec<u8>);
445
446impl BytesField {
447 pub fn new(data: Vec<u8>) -> Self {
448 Self(data)
449 }
450 pub fn from_slice(data: &[u8]) -> Self {
451 Self(data.to_vec())
452 }
453 pub fn as_bytes(&self) -> &[u8] {
454 &self.0
455 }
456 pub fn len(&self) -> usize {
457 self.0.len()
458 }
459 pub fn is_empty(&self) -> bool {
460 self.0.is_empty()
461 }
462
463 pub fn read_with_len(buf: &[u8], offset: usize, len: usize) -> Result<Self, FieldError> {
464 if buf.len() < offset + len {
465 return Err(FieldError::BufferTooShort {
466 offset,
467 need: len,
468 have: buf.len(),
469 });
470 }
471 Ok(Self(buf[offset..offset + len].to_vec()))
472 }
473
474 pub fn write_to(&self, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
475 if buf.len() < offset + self.0.len() {
476 return Err(FieldError::BufferTooShort {
477 offset,
478 need: self.0.len(),
479 have: buf.len(),
480 });
481 }
482 buf[offset..offset + self.0.len()].copy_from_slice(&self.0);
483 Ok(())
484 }
485}
486
487impl From<Vec<u8>> for BytesField {
488 fn from(v: Vec<u8>) -> Self {
489 Self(v)
490 }
491}
492
493impl From<&[u8]> for BytesField {
494 fn from(s: &[u8]) -> Self {
495 Self(s.to_vec())
496 }
497}
498
499#[derive(Debug, Clone, Copy)]
505pub struct FieldDesc {
506 pub name: &'static str,
507 pub offset: usize,
508 pub size: usize,
509 pub field_type: FieldType,
510}
511
512#[derive(Debug, Clone, Copy, PartialEq, Eq)]
514pub enum FieldType {
515 U8,
516 U16,
517 U32,
518 U64,
519 I8,
520 I16,
521 I32,
522 I64,
523 LEU16,
524 LEU32,
525 LEU64,
526 U24,
527 LEU24,
528 Bool,
529 Mac,
530 Ipv4,
531 Ipv6,
532 Bytes,
533 Str,
534 DnsName,
535}
536
537impl FieldType {
538 pub const fn name(&self) -> &'static str {
539 match self {
540 Self::U8 => "u8",
541 Self::U16 => "u16",
542 Self::U32 => "u32",
543 Self::U64 => "u64",
544 Self::I8 => "i8",
545 Self::I16 => "i16",
546 Self::I32 => "i32",
547 Self::I64 => "i64",
548 Self::LEU16 => "le_u16",
549 Self::LEU32 => "le_u32",
550 Self::LEU64 => "le_u64",
551 Self::U24 => "u24",
552 Self::LEU24 => "le_u24",
553 Self::Bool => "bool",
554 Self::Mac => "MAC",
555 Self::Ipv4 => "IPv4",
556 Self::Ipv6 => "IPv6",
557 Self::Bytes => "Bytes",
558 Self::Str => "Str",
559 Self::DnsName => "DnsName",
560 }
561 }
562
563 pub const fn size(&self) -> Option<usize> {
564 match self {
565 Self::U8 | Self::I8 | Self::Bool => Some(1),
566 Self::U16 | Self::I16 | Self::LEU16 => Some(2),
567 Self::U24 | Self::LEU24 => Some(3),
568 Self::U32 | Self::I32 | Self::LEU32 => Some(4),
569 Self::U64 | Self::I64 | Self::LEU64 => Some(8),
570 Self::Mac => Some(6),
571 Self::Ipv4 => Some(4),
572 Self::Ipv6 => Some(16),
573 Self::Bytes | Self::Str | Self::DnsName => None,
574 }
575 }
576}
577
578impl FieldDesc {
579 pub const fn new(
580 name: &'static str,
581 offset: usize,
582 size: usize,
583 field_type: FieldType,
584 ) -> Self {
585 Self {
586 name,
587 offset,
588 size,
589 field_type,
590 }
591 }
592
593 #[inline]
594 pub const fn with_offset(&self, base: usize) -> Self {
595 Self {
596 name: self.name,
597 offset: base + self.offset,
598 size: self.size,
599 field_type: self.field_type,
600 }
601 }
602}
603
604#[derive(Debug, Clone, PartialEq)]
606pub enum FieldValue {
607 U8(u8),
608 U16(u16),
609 U32(u32),
610 U64(u64),
611 I8(i8),
612 I16(i16),
613 I32(i32),
614 I64(i64),
615 Bool(bool),
616 Mac(MacAddress),
617 Ipv4(Ipv4Addr),
618 Ipv6(Ipv6Addr),
619 Bytes(Vec<u8>),
620 Str(String),
621 List(Vec<FieldValue>),
622}
623
624impl FieldValue {
625 pub fn read(buf: &[u8], desc: &FieldDesc) -> Result<Self, FieldError> {
627 match desc.field_type {
628 FieldType::U8 => Ok(Self::U8(u8::read(buf, desc.offset)?)),
629 FieldType::U16 => Ok(Self::U16(u16::read(buf, desc.offset)?)),
630 FieldType::U32 => Ok(Self::U32(u32::read(buf, desc.offset)?)),
631 FieldType::U64 => Ok(Self::U64(u64::read(buf, desc.offset)?)),
632 FieldType::I8 => Ok(Self::I8(read_i8(buf, desc.offset)?)),
633 FieldType::I16 => Ok(Self::I16(read_i16_be(buf, desc.offset)?)),
634 FieldType::I32 => Ok(Self::I32(read_i32_be(buf, desc.offset)?)),
635 FieldType::I64 => Ok(Self::I64(read_i64_be(buf, desc.offset)?)),
636 FieldType::LEU16 => Ok(Self::U16(read_u16_le(buf, desc.offset)?)),
637 FieldType::LEU32 => Ok(Self::U32(read_u32_le(buf, desc.offset)?)),
638 FieldType::LEU64 => Ok(Self::U64(read_u64_le(buf, desc.offset)?)),
639 FieldType::U24 => Ok(Self::U32(read_u24_be(buf, desc.offset)?)),
640 FieldType::LEU24 => Ok(Self::U32(read_u24_le(buf, desc.offset)?)),
641 FieldType::Bool => Ok(Self::Bool(u8::read(buf, desc.offset)? != 0)),
642 FieldType::Mac => Ok(Self::Mac(MacAddress::read(buf, desc.offset)?)),
643 FieldType::Ipv4 => Ok(Self::Ipv4(Ipv4Addr::read(buf, desc.offset)?)),
644 FieldType::Ipv6 => Ok(Self::Ipv6(Ipv6Addr::read(buf, desc.offset)?)),
645 FieldType::Bytes => {
646 let field = BytesField::read_with_len(buf, desc.offset, desc.size)?;
647 Ok(Self::Bytes(field.0))
648 }
649 FieldType::Str => {
650 let field = BytesField::read_with_len(buf, desc.offset, desc.size)?;
651 Ok(Self::Str(String::from_utf8_lossy(&field.0).into_owned()))
652 }
653 FieldType::DnsName => {
654 let field = BytesField::read_with_len(buf, desc.offset, desc.size)?;
657 Ok(Self::Bytes(field.0))
658 }
659 }
660 }
661
662 pub fn read_bytes(buf: &[u8], offset: usize, len: usize) -> Result<Self, FieldError> {
664 let field = BytesField::read_with_len(buf, offset, len)?;
665 Ok(Self::Bytes(field.0))
666 }
667
668 pub fn write(&self, buf: &mut [u8], desc: &FieldDesc) -> Result<(), FieldError> {
670 match (self, desc.field_type) {
671 (Self::U8(v), FieldType::U8) => v.write(buf, desc.offset),
672 (Self::U16(v), FieldType::U16) => v.write(buf, desc.offset),
673 (Self::U32(v), FieldType::U32) => v.write(buf, desc.offset),
674 (Self::U64(v), FieldType::U64) => v.write(buf, desc.offset),
675 (Self::I8(v), FieldType::I8) => write_i8(*v, buf, desc.offset),
676 (Self::I16(v), FieldType::I16) => write_i16_be(*v, buf, desc.offset),
677 (Self::I32(v), FieldType::I32) => write_i32_be(*v, buf, desc.offset),
678 (Self::I64(v), FieldType::I64) => write_i64_be(*v, buf, desc.offset),
679 (Self::U16(v), FieldType::LEU16) => write_u16_le(*v, buf, desc.offset),
680 (Self::U32(v), FieldType::LEU32) => write_u32_le(*v, buf, desc.offset),
681 (Self::U64(v), FieldType::LEU64) => write_u64_le(*v, buf, desc.offset),
682 (Self::U32(v), FieldType::U24) => write_u24_be(*v, buf, desc.offset),
683 (Self::U32(v), FieldType::LEU24) => write_u24_le(*v, buf, desc.offset),
684 (Self::Bool(v), FieldType::Bool) => {
685 (if *v { 1u8 } else { 0u8 }).write(buf, desc.offset)
686 }
687 (Self::Mac(v), FieldType::Mac) => v.write(buf, desc.offset),
688 (Self::Ipv4(v), FieldType::Ipv4) => v.write(buf, desc.offset),
689 (Self::Ipv6(v), FieldType::Ipv6) => v.write(buf, desc.offset),
690 (Self::Bytes(v), FieldType::Bytes) => BytesField(v.clone()).write_to(buf, desc.offset),
691 (Self::Str(v), FieldType::Str) => {
692 BytesField(v.as_bytes().to_vec()).write_to(buf, desc.offset)
693 }
694 _ => Err(FieldError::TypeMismatch {
695 expected: desc.field_type.name(),
696 got: self.type_name(),
697 }),
698 }
699 }
700
701 pub fn write_bytes(bytes: &[u8], buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
703 BytesField::from_slice(bytes).write_to(buf, offset)
704 }
705
706 pub const fn type_name(&self) -> &'static str {
707 match self {
708 Self::U8(_) => "u8",
709 Self::U16(_) => "u16",
710 Self::U32(_) => "u32",
711 Self::U64(_) => "u64",
712 Self::I8(_) => "i8",
713 Self::I16(_) => "i16",
714 Self::I32(_) => "i32",
715 Self::I64(_) => "i64",
716 Self::Bool(_) => "bool",
717 Self::Mac(_) => "MAC",
718 Self::Ipv4(_) => "IPv4",
719 Self::Ipv6(_) => "IPv6",
720 Self::Bytes(_) => "Bytes",
721 Self::Str(_) => "Str",
722 Self::List(_) => "List",
723 }
724 }
725
726 pub fn as_u8(&self) -> Option<u8> {
727 match self {
728 Self::U8(v) => Some(*v),
729 _ => None,
730 }
731 }
732
733 pub fn as_u16(&self) -> Option<u16> {
734 match self {
735 Self::U16(v) => Some(*v),
736 _ => None,
737 }
738 }
739
740 pub fn as_u32(&self) -> Option<u32> {
741 match self {
742 Self::U32(v) => Some(*v),
743 _ => None,
744 }
745 }
746
747 pub fn as_u64(&self) -> Option<u64> {
748 match self {
749 Self::U64(v) => Some(*v),
750 _ => None,
751 }
752 }
753
754 pub fn as_mac(&self) -> Option<MacAddress> {
755 match self {
756 Self::Mac(v) => Some(*v),
757 _ => None,
758 }
759 }
760
761 pub fn as_ipv4(&self) -> Option<Ipv4Addr> {
762 match self {
763 Self::Ipv4(v) => Some(*v),
764 _ => None,
765 }
766 }
767
768 pub fn as_ipv6(&self) -> Option<Ipv6Addr> {
769 match self {
770 Self::Ipv6(v) => Some(*v),
771 _ => None,
772 }
773 }
774
775 pub fn as_bytes(&self) -> Option<&[u8]> {
776 match self {
777 Self::Bytes(v) => Some(v),
778 _ => None,
779 }
780 }
781
782 pub fn as_i8(&self) -> Option<i8> {
783 match self {
784 Self::I8(v) => Some(*v),
785 _ => None,
786 }
787 }
788
789 pub fn as_i16(&self) -> Option<i16> {
790 match self {
791 Self::I16(v) => Some(*v),
792 _ => None,
793 }
794 }
795
796 pub fn as_i32(&self) -> Option<i32> {
797 match self {
798 Self::I32(v) => Some(*v),
799 _ => None,
800 }
801 }
802
803 pub fn as_i64(&self) -> Option<i64> {
804 match self {
805 Self::I64(v) => Some(*v),
806 _ => None,
807 }
808 }
809
810 pub fn as_bool(&self) -> Option<bool> {
811 match self {
812 Self::Bool(v) => Some(*v),
813 _ => None,
814 }
815 }
816
817 pub fn as_str(&self) -> Option<&str> {
818 match self {
819 Self::Str(v) => Some(v),
820 _ => None,
821 }
822 }
823
824 pub fn as_list(&self) -> Option<&[FieldValue]> {
825 match self {
826 Self::List(v) => Some(v),
827 _ => None,
828 }
829 }
830
831 pub fn to_bytes(&self) -> Vec<u8> {
833 match self {
834 Self::U8(v) => vec![*v],
835 Self::U16(v) => v.to_be_bytes().to_vec(),
836 Self::U32(v) => v.to_be_bytes().to_vec(),
837 Self::U64(v) => v.to_be_bytes().to_vec(),
838 Self::I8(v) => v.to_be_bytes().to_vec(),
839 Self::I16(v) => v.to_be_bytes().to_vec(),
840 Self::I32(v) => v.to_be_bytes().to_vec(),
841 Self::I64(v) => v.to_be_bytes().to_vec(),
842 Self::Bool(v) => vec![if *v { 1 } else { 0 }],
843 Self::Mac(v) => v.0.to_vec(),
844 Self::Ipv4(v) => v.octets().to_vec(),
845 Self::Ipv6(v) => v.octets().to_vec(),
846 Self::Bytes(v) => v.clone(),
847 Self::Str(v) => v.as_bytes().to_vec(),
848 Self::List(v) => v.iter().flat_map(|f| f.to_bytes()).collect(),
849 }
850 }
851}
852
853impl fmt::Display for FieldValue {
854 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
855 match self {
856 Self::U8(v) => write!(f, "{}", v),
857 Self::U16(v) => write!(f, "{:#06x}", v),
858 Self::U32(v) => write!(f, "{:#010x}", v),
859 Self::U64(v) => write!(f, "{:#018x}", v),
860 Self::I8(v) => write!(f, "{}", v),
861 Self::I16(v) => write!(f, "{}", v),
862 Self::I32(v) => write!(f, "{}", v),
863 Self::I64(v) => write!(f, "{}", v),
864 Self::Bool(v) => write!(f, "{}", v),
865 Self::Mac(v) => write!(f, "{}", v),
866 Self::Ipv4(v) => write!(f, "{}", v),
867 Self::Ipv6(v) => write!(f, "{}", v),
868 Self::Bytes(v) => {
869 write!(f, "0x")?;
870 for b in v {
871 write!(f, "{:02x}", b)?;
872 }
873 Ok(())
874 }
875 Self::Str(v) => write!(f, "{}", v),
876 Self::List(v) => {
877 write!(f, "[")?;
878 for (i, item) in v.iter().enumerate() {
879 if i > 0 {
880 write!(f, ", ")?;
881 }
882 write!(f, "{}", item)?;
883 }
884 write!(f, "]")
885 }
886 }
887 }
888}
889
890impl From<u8> for FieldValue {
892 fn from(v: u8) -> Self {
893 Self::U8(v)
894 }
895}
896impl From<u16> for FieldValue {
897 fn from(v: u16) -> Self {
898 Self::U16(v)
899 }
900}
901impl From<u32> for FieldValue {
902 fn from(v: u32) -> Self {
903 Self::U32(v)
904 }
905}
906impl From<u64> for FieldValue {
907 fn from(v: u64) -> Self {
908 Self::U64(v)
909 }
910}
911impl From<MacAddress> for FieldValue {
912 fn from(v: MacAddress) -> Self {
913 Self::Mac(v)
914 }
915}
916impl From<Ipv4Addr> for FieldValue {
917 fn from(v: Ipv4Addr) -> Self {
918 Self::Ipv4(v)
919 }
920}
921impl From<Ipv6Addr> for FieldValue {
922 fn from(v: Ipv6Addr) -> Self {
923 Self::Ipv6(v)
924 }
925}
926impl From<Vec<u8>> for FieldValue {
927 fn from(v: Vec<u8>) -> Self {
928 Self::Bytes(v)
929 }
930}
931impl From<&[u8]> for FieldValue {
932 fn from(v: &[u8]) -> Self {
933 Self::Bytes(v.to_vec())
934 }
935}
936impl From<i8> for FieldValue {
937 fn from(v: i8) -> Self {
938 Self::I8(v)
939 }
940}
941impl From<i16> for FieldValue {
942 fn from(v: i16) -> Self {
943 Self::I16(v)
944 }
945}
946impl From<i32> for FieldValue {
947 fn from(v: i32) -> Self {
948 Self::I32(v)
949 }
950}
951impl From<i64> for FieldValue {
952 fn from(v: i64) -> Self {
953 Self::I64(v)
954 }
955}
956impl From<bool> for FieldValue {
957 fn from(v: bool) -> Self {
958 Self::Bool(v)
959 }
960}
961impl From<String> for FieldValue {
962 fn from(v: String) -> Self {
963 Self::Str(v)
964 }
965}
966impl From<&str> for FieldValue {
967 fn from(v: &str) -> Self {
968 Self::Str(v.to_string())
969 }
970}
971
972#[inline]
977pub fn read_i8(buf: &[u8], offset: usize) -> Result<i8, FieldError> {
978 Ok(u8::read(buf, offset)? as i8)
979}
980
981#[inline]
982pub fn write_i8(v: i8, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
983 (v as u8).write(buf, offset)
984}
985
986#[inline]
987pub fn read_i16_be(buf: &[u8], offset: usize) -> Result<i16, FieldError> {
988 if buf.len() < offset + 2 {
989 return Err(FieldError::BufferTooShort {
990 offset,
991 need: 2,
992 have: buf.len(),
993 });
994 }
995 Ok(i16::from_be_bytes([buf[offset], buf[offset + 1]]))
996}
997
998#[inline]
999pub fn write_i16_be(v: i16, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1000 if buf.len() < offset + 2 {
1001 return Err(FieldError::BufferTooShort {
1002 offset,
1003 need: 2,
1004 have: buf.len(),
1005 });
1006 }
1007 buf[offset..offset + 2].copy_from_slice(&v.to_be_bytes());
1008 Ok(())
1009}
1010
1011#[inline]
1012pub fn read_i32_be(buf: &[u8], offset: usize) -> Result<i32, FieldError> {
1013 if buf.len() < offset + 4 {
1014 return Err(FieldError::BufferTooShort {
1015 offset,
1016 need: 4,
1017 have: buf.len(),
1018 });
1019 }
1020 Ok(i32::from_be_bytes([
1021 buf[offset],
1022 buf[offset + 1],
1023 buf[offset + 2],
1024 buf[offset + 3],
1025 ]))
1026}
1027
1028#[inline]
1029pub fn write_i32_be(v: i32, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1030 if buf.len() < offset + 4 {
1031 return Err(FieldError::BufferTooShort {
1032 offset,
1033 need: 4,
1034 have: buf.len(),
1035 });
1036 }
1037 buf[offset..offset + 4].copy_from_slice(&v.to_be_bytes());
1038 Ok(())
1039}
1040
1041#[inline]
1042pub fn read_i64_be(buf: &[u8], offset: usize) -> Result<i64, FieldError> {
1043 if buf.len() < offset + 8 {
1044 return Err(FieldError::BufferTooShort {
1045 offset,
1046 need: 8,
1047 have: buf.len(),
1048 });
1049 }
1050 let mut bytes = [0u8; 8];
1051 bytes.copy_from_slice(&buf[offset..offset + 8]);
1052 Ok(i64::from_be_bytes(bytes))
1053}
1054
1055#[inline]
1056pub fn write_i64_be(v: i64, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1057 if buf.len() < offset + 8 {
1058 return Err(FieldError::BufferTooShort {
1059 offset,
1060 need: 8,
1061 have: buf.len(),
1062 });
1063 }
1064 buf[offset..offset + 8].copy_from_slice(&v.to_be_bytes());
1065 Ok(())
1066}
1067
1068#[inline]
1069pub fn read_u16_le(buf: &[u8], offset: usize) -> Result<u16, FieldError> {
1070 if buf.len() < offset + 2 {
1071 return Err(FieldError::BufferTooShort {
1072 offset,
1073 need: 2,
1074 have: buf.len(),
1075 });
1076 }
1077 Ok(u16::from_le_bytes([buf[offset], buf[offset + 1]]))
1078}
1079
1080#[inline]
1081pub fn write_u16_le(v: u16, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1082 if buf.len() < offset + 2 {
1083 return Err(FieldError::BufferTooShort {
1084 offset,
1085 need: 2,
1086 have: buf.len(),
1087 });
1088 }
1089 buf[offset..offset + 2].copy_from_slice(&v.to_le_bytes());
1090 Ok(())
1091}
1092
1093#[inline]
1094pub fn read_u32_le(buf: &[u8], offset: usize) -> Result<u32, FieldError> {
1095 if buf.len() < offset + 4 {
1096 return Err(FieldError::BufferTooShort {
1097 offset,
1098 need: 4,
1099 have: buf.len(),
1100 });
1101 }
1102 Ok(u32::from_le_bytes([
1103 buf[offset],
1104 buf[offset + 1],
1105 buf[offset + 2],
1106 buf[offset + 3],
1107 ]))
1108}
1109
1110#[inline]
1111pub fn write_u32_le(v: u32, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1112 if buf.len() < offset + 4 {
1113 return Err(FieldError::BufferTooShort {
1114 offset,
1115 need: 4,
1116 have: buf.len(),
1117 });
1118 }
1119 buf[offset..offset + 4].copy_from_slice(&v.to_le_bytes());
1120 Ok(())
1121}
1122
1123#[inline]
1124pub fn read_u64_le(buf: &[u8], offset: usize) -> Result<u64, FieldError> {
1125 if buf.len() < offset + 8 {
1126 return Err(FieldError::BufferTooShort {
1127 offset,
1128 need: 8,
1129 have: buf.len(),
1130 });
1131 }
1132 let mut bytes = [0u8; 8];
1133 bytes.copy_from_slice(&buf[offset..offset + 8]);
1134 Ok(u64::from_le_bytes(bytes))
1135}
1136
1137#[inline]
1138pub fn write_u64_le(v: u64, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1139 if buf.len() < offset + 8 {
1140 return Err(FieldError::BufferTooShort {
1141 offset,
1142 need: 8,
1143 have: buf.len(),
1144 });
1145 }
1146 buf[offset..offset + 8].copy_from_slice(&v.to_le_bytes());
1147 Ok(())
1148}
1149
1150#[inline]
1151pub fn read_u24_be(buf: &[u8], offset: usize) -> Result<u32, FieldError> {
1152 if buf.len() < offset + 3 {
1153 return Err(FieldError::BufferTooShort {
1154 offset,
1155 need: 3,
1156 have: buf.len(),
1157 });
1158 }
1159 Ok(((buf[offset] as u32) << 16) | ((buf[offset + 1] as u32) << 8) | (buf[offset + 2] as u32))
1160}
1161
1162#[inline]
1163pub fn write_u24_be(v: u32, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1164 if buf.len() < offset + 3 {
1165 return Err(FieldError::BufferTooShort {
1166 offset,
1167 need: 3,
1168 have: buf.len(),
1169 });
1170 }
1171 buf[offset] = ((v >> 16) & 0xFF) as u8;
1172 buf[offset + 1] = ((v >> 8) & 0xFF) as u8;
1173 buf[offset + 2] = (v & 0xFF) as u8;
1174 Ok(())
1175}
1176
1177#[inline]
1178pub fn read_u24_le(buf: &[u8], offset: usize) -> Result<u32, FieldError> {
1179 if buf.len() < offset + 3 {
1180 return Err(FieldError::BufferTooShort {
1181 offset,
1182 need: 3,
1183 have: buf.len(),
1184 });
1185 }
1186 Ok((buf[offset] as u32) | ((buf[offset + 1] as u32) << 8) | ((buf[offset + 2] as u32) << 16))
1187}
1188
1189#[inline]
1190pub fn write_u24_le(v: u32, buf: &mut [u8], offset: usize) -> Result<(), FieldError> {
1191 if buf.len() < offset + 3 {
1192 return Err(FieldError::BufferTooShort {
1193 offset,
1194 need: 3,
1195 have: buf.len(),
1196 });
1197 }
1198 buf[offset] = (v & 0xFF) as u8;
1199 buf[offset + 1] = ((v >> 8) & 0xFF) as u8;
1200 buf[offset + 2] = ((v >> 16) & 0xFF) as u8;
1201 Ok(())
1202}
1203
1204#[inline]
1213pub fn read_bits_be(buf: &[u8], bit_offset: usize, num_bits: usize) -> Result<u64, FieldError> {
1214 if num_bits == 0 || num_bits > 64 {
1215 return Err(FieldError::InvalidValue(format!(
1216 "num_bits must be 1..=64, got {}",
1217 num_bits
1218 )));
1219 }
1220 let end_bit = bit_offset + num_bits;
1221 let end_byte = (end_bit + 7) / 8;
1222 if end_byte > buf.len() {
1223 return Err(FieldError::BufferTooShort {
1224 offset: bit_offset / 8,
1225 need: end_byte,
1226 have: buf.len(),
1227 });
1228 }
1229
1230 let mut result: u64 = 0;
1231 for i in 0..num_bits {
1232 let bit_pos = bit_offset + i;
1233 let byte_idx = bit_pos / 8;
1234 let bit_idx = 7 - (bit_pos % 8); if (buf[byte_idx] >> bit_idx) & 1 != 0 {
1236 result |= 1u64 << (num_bits - 1 - i);
1237 }
1238 }
1239 Ok(result)
1240}
1241
1242#[inline]
1247pub fn write_bits_be(
1248 buf: &mut [u8],
1249 bit_offset: usize,
1250 num_bits: usize,
1251 value: u64,
1252) -> Result<(), FieldError> {
1253 if num_bits == 0 || num_bits > 64 {
1254 return Err(FieldError::InvalidValue(format!(
1255 "num_bits must be 1..=64, got {}",
1256 num_bits
1257 )));
1258 }
1259 let end_bit = bit_offset + num_bits;
1260 let end_byte = (end_bit + 7) / 8;
1261 if end_byte > buf.len() {
1262 return Err(FieldError::BufferTooShort {
1263 offset: bit_offset / 8,
1264 need: end_byte,
1265 have: buf.len(),
1266 });
1267 }
1268
1269 for i in 0..num_bits {
1270 let bit_pos = bit_offset + i;
1271 let byte_idx = bit_pos / 8;
1272 let bit_idx = 7 - (bit_pos % 8); let bit_val = (value >> (num_bits - 1 - i)) & 1;
1274 if bit_val != 0 {
1275 buf[byte_idx] |= 1 << bit_idx;
1276 } else {
1277 buf[byte_idx] &= !(1 << bit_idx);
1278 }
1279 }
1280 Ok(())
1281}
1282
1283#[inline]
1285pub fn read_bits_le(buf: &[u8], bit_offset: usize, num_bits: usize) -> Result<u64, FieldError> {
1286 if num_bits == 0 || num_bits > 64 {
1287 return Err(FieldError::InvalidValue(format!(
1288 "num_bits must be 1..=64, got {}",
1289 num_bits
1290 )));
1291 }
1292 let end_bit = bit_offset + num_bits;
1293 let end_byte = (end_bit + 7) / 8;
1294 if end_byte > buf.len() {
1295 return Err(FieldError::BufferTooShort {
1296 offset: bit_offset / 8,
1297 need: end_byte,
1298 have: buf.len(),
1299 });
1300 }
1301
1302 let mut result: u64 = 0;
1303 for i in 0..num_bits {
1304 let bit_pos = bit_offset + i;
1305 let byte_idx = bit_pos / 8;
1306 let bit_idx = bit_pos % 8; if (buf[byte_idx] >> bit_idx) & 1 != 0 {
1308 result |= 1u64 << i;
1309 }
1310 }
1311 Ok(result)
1312}
1313
1314#[inline]
1316pub fn write_bits_le(
1317 buf: &mut [u8],
1318 bit_offset: usize,
1319 num_bits: usize,
1320 value: u64,
1321) -> Result<(), FieldError> {
1322 if num_bits == 0 || num_bits > 64 {
1323 return Err(FieldError::InvalidValue(format!(
1324 "num_bits must be 1..=64, got {}",
1325 num_bits
1326 )));
1327 }
1328 let end_bit = bit_offset + num_bits;
1329 let end_byte = (end_bit + 7) / 8;
1330 if end_byte > buf.len() {
1331 return Err(FieldError::BufferTooShort {
1332 offset: bit_offset / 8,
1333 need: end_byte,
1334 have: buf.len(),
1335 });
1336 }
1337
1338 for i in 0..num_bits {
1339 let bit_pos = bit_offset + i;
1340 let byte_idx = bit_pos / 8;
1341 let bit_idx = bit_pos % 8; let bit_val = (value >> i) & 1;
1343 if bit_val != 0 {
1344 buf[byte_idx] |= 1 << bit_idx;
1345 } else {
1346 buf[byte_idx] &= !(1 << bit_idx);
1347 }
1348 }
1349 Ok(())
1350}
1351
1352#[cfg(test)]
1353mod tests {
1354 use super::*;
1355
1356 #[test]
1357 fn test_ipv6_field() {
1358 let ip = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1);
1359 let mut buf = [0u8; 20];
1360 ip.write(&mut buf, 2).unwrap();
1361 let read_ip = Ipv6Addr::read(&buf, 2).unwrap();
1362 assert_eq!(ip, read_ip);
1363 }
1364
1365 #[test]
1366 fn test_bytes_field() {
1367 let data = vec![0xde, 0xad, 0xbe, 0xef];
1368 let mut buf = [0u8; 10];
1369 BytesField(data.clone()).write_to(&mut buf, 2).unwrap();
1370 let read = BytesField::read_with_len(&buf, 2, 4).unwrap();
1371 assert_eq!(read.0, data);
1372 }
1373
1374 #[test]
1375 fn test_field_value_ipv6() {
1376 let ip = Ipv6Addr::LOCALHOST;
1377 let val = FieldValue::from(ip);
1378 assert_eq!(val.as_ipv6(), Some(ip));
1379 assert_eq!(val.type_name(), "IPv6");
1380 }
1381
1382 #[test]
1383 fn test_mac_multicast() {
1384 let mcast = MacAddress::from_ipv4_multicast(Ipv4Addr::new(224, 0, 0, 1));
1385 assert!(mcast.is_ipv4_multicast());
1386 assert!(mcast.is_multicast());
1387 }
1388
1389 #[test]
1390 fn test_u64_field() {
1391 let mut buf = [0u8; 10];
1392 let val: u64 = 0x0102030405060708;
1393 val.write(&mut buf, 1).unwrap();
1394 assert_eq!(u64::read(&buf, 1).unwrap(), val);
1395 }
1396
1397 #[test]
1398 fn test_i8_read_write() {
1399 let mut buf = [0u8; 4];
1400 write_i8(-42, &mut buf, 1).unwrap();
1401 assert_eq!(read_i8(&buf, 1).unwrap(), -42);
1402 write_i8(127, &mut buf, 0).unwrap();
1403 assert_eq!(read_i8(&buf, 0).unwrap(), 127);
1404 }
1405
1406 #[test]
1407 fn test_i16_read_write() {
1408 let mut buf = [0u8; 4];
1409 write_i16_be(-1234, &mut buf, 1).unwrap();
1410 assert_eq!(read_i16_be(&buf, 1).unwrap(), -1234);
1411 }
1412
1413 #[test]
1414 fn test_i32_read_write() {
1415 let mut buf = [0u8; 8];
1416 write_i32_be(-100_000, &mut buf, 2).unwrap();
1417 assert_eq!(read_i32_be(&buf, 2).unwrap(), -100_000);
1418 }
1419
1420 #[test]
1421 fn test_i64_read_write() {
1422 let mut buf = [0u8; 10];
1423 write_i64_be(-1_000_000_000_000, &mut buf, 1).unwrap();
1424 assert_eq!(read_i64_be(&buf, 1).unwrap(), -1_000_000_000_000);
1425 }
1426
1427 #[test]
1428 fn test_u16_le_read_write() {
1429 let mut buf = [0u8; 4];
1430 write_u16_le(0x0102, &mut buf, 1).unwrap();
1431 assert_eq!(buf[1], 0x02); assert_eq!(buf[2], 0x01);
1433 assert_eq!(read_u16_le(&buf, 1).unwrap(), 0x0102);
1434 }
1435
1436 #[test]
1437 fn test_u32_le_read_write() {
1438 let mut buf = [0u8; 6];
1439 write_u32_le(0x01020304, &mut buf, 1).unwrap();
1440 assert_eq!(read_u32_le(&buf, 1).unwrap(), 0x01020304);
1441 }
1442
1443 #[test]
1444 fn test_u64_le_read_write() {
1445 let mut buf = [0u8; 10];
1446 write_u64_le(0x0102030405060708, &mut buf, 1).unwrap();
1447 assert_eq!(read_u64_le(&buf, 1).unwrap(), 0x0102030405060708);
1448 }
1449
1450 #[test]
1451 fn test_u24_be_read_write() {
1452 let mut buf = [0u8; 5];
1453 write_u24_be(0x123456, &mut buf, 1).unwrap();
1454 assert_eq!(buf[1], 0x12);
1455 assert_eq!(buf[2], 0x34);
1456 assert_eq!(buf[3], 0x56);
1457 assert_eq!(read_u24_be(&buf, 1).unwrap(), 0x123456);
1458 }
1459
1460 #[test]
1461 fn test_u24_le_read_write() {
1462 let mut buf = [0u8; 5];
1463 write_u24_le(0x123456, &mut buf, 1).unwrap();
1464 assert_eq!(buf[1], 0x56); assert_eq!(buf[2], 0x34);
1466 assert_eq!(buf[3], 0x12);
1467 assert_eq!(read_u24_le(&buf, 1).unwrap(), 0x123456);
1468 }
1469
1470 #[test]
1471 fn test_read_bits_be() {
1472 let buf = [0xA5u8];
1474 assert_eq!(read_bits_be(&buf, 0, 1).unwrap(), 1); assert_eq!(read_bits_be(&buf, 1, 1).unwrap(), 0); assert_eq!(read_bits_be(&buf, 0, 4).unwrap(), 0b1010); assert_eq!(read_bits_be(&buf, 4, 4).unwrap(), 0b0101); assert_eq!(read_bits_be(&buf, 0, 8).unwrap(), 0xA5); }
1480
1481 #[test]
1482 fn test_write_bits_be() {
1483 let mut buf = [0u8; 2];
1484 write_bits_be(&mut buf, 0, 4, 0b1010).unwrap();
1485 write_bits_be(&mut buf, 4, 4, 0b0101).unwrap();
1486 assert_eq!(buf[0], 0xA5);
1487 }
1488
1489 #[test]
1490 fn test_bits_be_cross_byte() {
1491 let buf = [0b1100_0011, 0b1010_0101];
1492 assert_eq!(read_bits_be(&buf, 6, 4).unwrap(), 0b1110);
1494 }
1495
1496 #[test]
1497 fn test_read_bits_le() {
1498 let buf = [0xA5u8]; assert_eq!(read_bits_le(&buf, 0, 1).unwrap(), 1); assert_eq!(read_bits_le(&buf, 1, 1).unwrap(), 0); assert_eq!(read_bits_le(&buf, 0, 4).unwrap(), 0b0101); assert_eq!(read_bits_le(&buf, 4, 4).unwrap(), 0b1010); }
1505
1506 #[test]
1507 fn test_write_bits_le() {
1508 let mut buf = [0u8; 2];
1509 write_bits_le(&mut buf, 0, 3, 0b101).unwrap();
1511 assert_eq!(buf[0] & 0x07, 0b101);
1512 }
1513
1514 #[test]
1515 fn test_field_value_new_types() {
1516 assert_eq!(FieldValue::from(-42i8).as_i8(), Some(-42));
1517 assert_eq!(FieldValue::from(-1000i16).as_i16(), Some(-1000));
1518 assert_eq!(FieldValue::from(-100_000i32).as_i32(), Some(-100_000));
1519 assert_eq!(FieldValue::from(-1i64).as_i64(), Some(-1));
1520 assert_eq!(FieldValue::from(true).as_bool(), Some(true));
1521 assert_eq!(FieldValue::from(false).as_bool(), Some(false));
1522 assert_eq!(FieldValue::from("hello").as_str(), Some("hello"));
1523 }
1524
1525 #[test]
1526 fn test_field_value_list() {
1527 let list = FieldValue::List(vec![
1528 FieldValue::U16(1),
1529 FieldValue::U16(2),
1530 FieldValue::U16(3),
1531 ]);
1532 assert_eq!(list.as_list().unwrap().len(), 3);
1533 assert_eq!(list.to_string(), "[0x0001, 0x0002, 0x0003]");
1534 }
1535
1536 #[test]
1537 fn test_buffer_too_short_errors() {
1538 let buf = [0u8; 2];
1539 assert!(read_u24_be(&buf, 0).is_err());
1540 assert!(read_u32_le(&buf, 0).is_err());
1541 assert!(read_i32_be(&buf, 0).is_err());
1542 assert!(read_bits_be(&buf, 0, 24).is_err());
1543 }
1544}