1use bit_register::{NumBytes, TryFromBits, TryIntoBits, bit_register};
2
3use crate::{
4 MctpPacketError,
5 error::MctpPacketResult,
6 medium::{
7 MctpMedium, MctpMediumFrame,
8 util::{One, Zero},
9 },
10};
11
12#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14pub struct SmbusEspiMedium;
15
16#[derive(Debug, Copy, Clone, PartialEq, Eq)]
17#[cfg_attr(feature = "defmt", derive(defmt::Format))]
18pub struct SmbusEspiReplyContext {
19 pub destination_slave_address: u8,
20 pub source_slave_address: u8,
21}
22
23impl MctpMedium for SmbusEspiMedium {
24 type Frame = SmbusEspiMediumFrame;
25 type Error = &'static str;
26 type ReplyContext = SmbusEspiReplyContext;
27
28 fn deserialize<'buf>(
29 &self,
30 packet: &'buf [u8],
31 ) -> MctpPacketResult<(Self::Frame, &'buf [u8]), Self> {
32 if packet.len() < 4 {
34 return Err(MctpPacketError::MediumError(
35 "Packet too short to parse smbus header",
36 ));
37 }
38
39 let header_value =
40 u32::from_be_bytes(packet[0..4].try_into().map_err(|_| {
41 MctpPacketError::MediumError("Packet too short to parse smbus header")
42 })?);
43 let packet = &packet[4..];
45 let header = SmbusEspiMediumHeader::try_from(header_value)
46 .map_err(|_| MctpPacketError::MediumError("Invalid smbus header"))?;
47 if header.byte_count as usize + 1 > packet.len() {
48 return Err(MctpPacketError::MediumError(
49 "Packet too short to parse smbus body and PEC",
50 ));
51 }
52 let pec = packet[header.byte_count as usize];
53 let packet = &packet[..header.byte_count as usize];
55 Ok((SmbusEspiMediumFrame { header, pec }, packet))
56 }
57
58 fn serialize<'buf, F>(
59 &self,
60 reply_context: Self::ReplyContext,
61 buffer: &'buf mut [u8],
62 message_writer: F,
63 ) -> MctpPacketResult<&'buf [u8], Self>
64 where
65 F: for<'a> FnOnce(&'a mut [u8]) -> MctpPacketResult<usize, Self>,
66 {
67 if buffer.len() < 5 {
69 return Err(MctpPacketError::MediumError(
70 "Buffer too small for smbus frame",
71 ));
72 }
73
74 let (header_slice, body) = buffer.split_at_mut(4);
76
77 if body.is_empty() {
79 return Err(MctpPacketError::MediumError("No space for PEC byte"));
80 }
81 let available_body_len = body.len() - 1; let body_len = message_writer(&mut body[..available_body_len])?;
83
84 let header = SmbusEspiMediumHeader {
86 destination_slave_address: reply_context.source_slave_address,
87 source_slave_address: reply_context.destination_slave_address,
88 byte_count: body_len as u8,
89 command_code: SmbusCommandCode::Mctp,
90 ..Default::default()
91 };
92 let header_value =
93 TryInto::<u32>::try_into(header).map_err(MctpPacketError::MediumError)?;
94 header_slice.copy_from_slice(&header_value.to_be_bytes());
95
96 let pec_value = smbus_pec::pec(&buffer[0..4 + body_len]);
98 buffer[4 + body_len] = pec_value;
99
100 Ok(&buffer[0..4 + body_len + 1])
102 }
103
104 fn max_message_body_size(&self) -> usize {
106 32
107 }
108}
109
110#[repr(u8)]
111#[derive(
112 Debug, Copy, Clone, PartialEq, Eq, num_enum::IntoPrimitive, num_enum::TryFromPrimitive, Default,
113)]
114#[cfg_attr(feature = "defmt", derive(defmt::Format))]
115enum SmbusCommandCode {
116 #[default]
117 Mctp = 0x0F,
118}
119impl TryFromBits<u32> for SmbusCommandCode {
120 fn try_from_bits(bits: u32) -> Result<Self, &'static str> {
121 if bits > 0xFF {
122 Err("Command code out of range")
123 } else {
124 SmbusCommandCode::try_from(bits as u8).map_err(|_| "Invalid command code")
125 }
126 }
127}
128impl TryIntoBits<u32> for SmbusCommandCode {
129 fn try_into_bits(self) -> Result<u32, &'static str> {
130 Ok(Into::<u8>::into(self) as u32)
131 }
132}
133impl NumBytes for SmbusCommandCode {
134 const NUM_BYTES: usize = 1;
135}
136
137bit_register! {
141 #[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
142 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
143 struct SmbusEspiMediumHeader: little_endian u32 {
144 pub destination_slave_address: u8 => [25:31],
145 pub _reserved1: Zero => [24],
146 pub command_code: SmbusCommandCode => [16:23],
147 pub byte_count: u8 => [8:15],
148 pub source_slave_address: u8 => [1:7],
149 pub _reserved2: One => [0],
150 }
151}
152
153#[derive(Copy, Clone, PartialEq, Eq, Debug)]
154#[cfg_attr(feature = "defmt", derive(defmt::Format))]
155pub struct SmbusEspiMediumFrame {
156 header: SmbusEspiMediumHeader,
157 pec: u8,
158}
159
160impl SmbusEspiReplyContext {
161 fn new(frame: SmbusEspiMediumFrame) -> Self {
162 Self {
163 destination_slave_address: frame.header.destination_slave_address,
164 source_slave_address: frame.header.source_slave_address,
165 }
166 }
167}
168
169impl MctpMediumFrame<SmbusEspiMedium> for SmbusEspiMediumFrame {
170 fn packet_size(&self) -> usize {
171 self.header.byte_count as usize
172 }
173
174 fn reply_context(&self) -> SmbusEspiReplyContext {
175 SmbusEspiReplyContext::new(*self)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 extern crate std;
182 use super::*;
183
184 #[test]
185 fn test_deserialize_valid_packet() {
186 let medium = SmbusEspiMedium;
187
188 let header = SmbusEspiMediumHeader {
191 destination_slave_address: 0x20,
192 source_slave_address: 0x10,
193 command_code: SmbusCommandCode::Mctp,
194 byte_count: 4,
195 ..Default::default()
196 };
197 let header_value: u32 = header.try_into().unwrap();
198 let header_bytes = header_value.to_be_bytes();
199
200 let payload = [0xAA, 0xBB, 0xCC, 0xDD]; let mut combined = [0u8; 8];
202 combined[0..4].copy_from_slice(&header_bytes);
203 combined[4..8].copy_from_slice(&payload);
204 let pec = smbus_pec::pec(&combined);
205
206 let mut packet = [0u8; 9];
207 packet[0..4].copy_from_slice(&header_bytes);
208 packet[4..8].copy_from_slice(&payload);
209 packet[8] = pec;
210
211 let result = medium.deserialize(&packet).unwrap();
212 let (frame, body) = result;
213
214 assert_eq!(frame.header.destination_slave_address, 0x20);
215 assert_eq!(frame.header.source_slave_address, 0x10);
216 assert_eq!(frame.header.command_code, SmbusCommandCode::Mctp);
217 assert_eq!(frame.header.byte_count, 4);
218 assert_eq!(frame.pec, pec);
219 assert_eq!(body, &payload);
220 }
221
222 #[test]
223 fn test_deserialize_packet_too_short_header() {
224 let medium = SmbusEspiMedium;
225 let short_packet = [0x01, 0x02]; let result = medium.deserialize(&short_packet);
228 assert_eq!(
229 result,
230 Err(MctpPacketError::MediumError(
231 "Packet too short to parse smbus header"
232 ))
233 );
234 }
235
236 #[test]
237 fn test_deserialize_packet_too_short_body() {
238 let medium = SmbusEspiMedium;
239
240 let header_bytes = [
242 0x20, 0x0F, 0x0A, 0x21, ];
247
248 let short_payload = [0xAA, 0xBB]; let mut packet = [0u8; 6];
251 packet[0..4].copy_from_slice(&header_bytes);
252 packet[4..6].copy_from_slice(&short_payload);
253
254 let result = medium.deserialize(&packet);
255 assert_eq!(
256 result,
257 Err(MctpPacketError::MediumError(
258 "Packet too short to parse smbus body and PEC"
259 ))
260 );
261 }
262
263 #[test]
264 fn test_deserialize_invalid_header() {
265 let medium = SmbusEspiMedium;
266
267 let invalid_header_bytes = [
269 0x20, 0xFF, 0x04, 0x20, ];
274
275 let payload = [0xAA, 0xBB, 0xCC, 0xDD];
276 let pec = 0x00; let mut packet = [0u8; 9];
279 packet[0..4].copy_from_slice(&invalid_header_bytes);
280 packet[4..8].copy_from_slice(&payload);
281 packet[8] = pec;
282
283 let result = medium.deserialize(&packet);
284 assert_eq!(
285 result,
286 Err(MctpPacketError::MediumError("Invalid smbus header"))
287 );
288 }
289
290 #[test]
291 fn test_deserialize_zero_byte_count() {
292 let medium = SmbusEspiMedium;
293
294 let header_bytes = [
295 0x20, 0x0F, 0x00, 0x21, ];
300
301 let pec = smbus_pec::pec(&header_bytes);
302
303 let mut packet = [0u8; 5];
304 packet[0..4].copy_from_slice(&header_bytes);
305 packet[4] = pec;
306
307 let result = medium.deserialize(&packet).unwrap();
308 let (frame, body) = result;
309
310 assert_eq!(frame.header.byte_count, 0);
311 assert_eq!(frame.pec, pec);
312 assert_eq!(body.len(), 0);
313 }
314
315 #[test]
316 fn test_serialize_valid_packet() {
317 let medium = SmbusEspiMedium;
318 let reply_context = SmbusEspiReplyContext {
319 destination_slave_address: 0x20,
320 source_slave_address: 0x10,
321 };
322
323 let mut buffer = [0u8; 64];
324 let test_payload = [0xAA, 0xBB, 0xCC, 0xDD];
325
326 let result = medium
327 .serialize(reply_context, &mut buffer, |buf| {
328 buf[..test_payload.len()].copy_from_slice(&test_payload);
329 Ok(test_payload.len())
330 })
331 .unwrap();
332
333 assert_eq!(result.len(), 9);
336
337 let header_value = u32::from_be_bytes([result[0], result[1], result[2], result[3]]);
339 let header = SmbusEspiMediumHeader::try_from(header_value).unwrap();
340
341 assert_eq!(header.destination_slave_address, 0x10); assert_eq!(header.source_slave_address, 0x20); assert_eq!(header.command_code, SmbusCommandCode::Mctp);
345 assert_eq!(header.byte_count, 4);
346
347 assert_eq!(&result[4..8], &test_payload);
349
350 let expected_pec = smbus_pec::pec(&result[0..8]);
352 assert_eq!(result[8], expected_pec);
353 }
354
355 #[test]
356 fn test_serialize_buffer_too_small() {
357 let medium = SmbusEspiMedium;
358 let reply_context = SmbusEspiReplyContext {
359 destination_slave_address: 0x20,
360 source_slave_address: 0x10,
361 };
362
363 let mut small_buffer = [0u8; 4]; let result = medium.serialize(reply_context, &mut small_buffer, |_| Ok(0));
366
367 assert_eq!(
368 result,
369 Err(MctpPacketError::MediumError(
370 "Buffer too small for smbus frame"
371 ))
372 );
373 }
374
375 #[test]
376 fn test_serialize_minimal_buffer() {
377 let medium = SmbusEspiMedium;
378 let reply_context = SmbusEspiReplyContext {
379 destination_slave_address: 0x20,
380 source_slave_address: 0x10,
381 };
382
383 let mut minimal_buffer = [0u8; 5]; let result = medium
386 .serialize(
387 reply_context,
388 &mut minimal_buffer,
389 |_| Ok(0), )
391 .unwrap();
392
393 assert_eq!(result.len(), 5);
394
395 let header_value = u32::from_be_bytes([result[0], result[1], result[2], result[3]]);
397 let header = SmbusEspiMediumHeader::try_from(header_value).unwrap();
398 assert_eq!(header.byte_count, 0);
399
400 let expected_pec = smbus_pec::pec(&result[0..4]);
402 assert_eq!(result[4], expected_pec);
403 }
404
405 #[test]
406 fn test_serialize_max_payload() {
407 let medium = SmbusEspiMedium;
408 let reply_context = SmbusEspiReplyContext {
409 destination_slave_address: 0x20,
410 source_slave_address: 0x10,
411 };
412
413 let max_payload = [0x55u8; 255];
415 let mut buffer = [0u8; 260]; let result = medium
418 .serialize(reply_context, &mut buffer, |buf| {
419 let copy_len = max_payload.len().min(buf.len());
420 buf[..copy_len].copy_from_slice(&max_payload[..copy_len]);
421 Ok(copy_len)
422 })
423 .unwrap();
424
425 assert_eq!(result.len(), 260); let header_value = u32::from_be_bytes([result[0], result[1], result[2], result[3]]);
429 let header = SmbusEspiMediumHeader::try_from(header_value).unwrap();
430 assert_eq!(header.byte_count, 255);
431
432 assert_eq!(&result[4..259], &max_payload[..]);
434
435 let expected_pec = smbus_pec::pec(&result[0..259]);
437 assert_eq!(result[259], expected_pec);
438 }
439
440 #[test]
441 fn test_serialize_message_writer_error() {
442 let medium = SmbusEspiMedium;
443 let reply_context = SmbusEspiReplyContext {
444 destination_slave_address: 0x20,
445 source_slave_address: 0x10,
446 };
447
448 let mut buffer = [0u8; 64];
449
450 let result = medium.serialize(reply_context, &mut buffer, |_| {
451 Err(MctpPacketError::MediumError("Test error"))
452 });
453
454 assert_eq!(result, Err(MctpPacketError::MediumError("Test error")));
455 }
456
457 #[test]
458 fn test_roundtrip_serialization_deserialization() {
459 let medium = SmbusEspiMedium;
460 let original_context = SmbusEspiReplyContext {
461 destination_slave_address: 0x42,
462 source_slave_address: 0x24,
463 };
464
465 let original_payload = [0x11, 0x22, 0x33, 0x44, 0x55];
466 let mut buffer = [0u8; 64];
467
468 let serialized = medium
470 .serialize(original_context, &mut buffer, |buf| {
471 buf[..original_payload.len()].copy_from_slice(&original_payload);
472 Ok(original_payload.len())
473 })
474 .unwrap();
475
476 let (frame, deserialized_payload) = medium.deserialize(serialized).unwrap();
478
479 assert_eq!(deserialized_payload, &original_payload);
481 assert_eq!(frame.header.destination_slave_address, 0x24); assert_eq!(frame.header.source_slave_address, 0x42); assert_eq!(frame.header.command_code, SmbusCommandCode::Mctp);
484 assert_eq!(frame.header.byte_count, original_payload.len() as u8);
485
486 let expected_pec = smbus_pec::pec(&serialized[0..serialized.len() - 1]);
488 assert_eq!(frame.pec, expected_pec);
489 }
490
491 #[test]
492 fn test_frame_packet_size() {
493 let frame = SmbusEspiMediumFrame {
494 header: SmbusEspiMediumHeader {
495 byte_count: 42,
496 ..Default::default()
497 },
498 pec: 0,
499 };
500
501 assert_eq!(frame.packet_size(), 42);
502 }
503
504 #[test]
505 fn test_frame_reply_context() {
506 let frame = SmbusEspiMediumFrame {
507 header: SmbusEspiMediumHeader {
508 destination_slave_address: 0x30,
509 source_slave_address: 0x40,
510 ..Default::default()
511 },
512 pec: 0,
513 };
514
515 let context = frame.reply_context();
516 assert_eq!(context.destination_slave_address, 0x30);
517 assert_eq!(context.source_slave_address, 0x40);
518 }
519
520 #[test]
521 fn test_smbus_command_code_conversion() {
522 assert_eq!(
524 SmbusCommandCode::try_from_bits(0x0F).unwrap(),
525 SmbusCommandCode::Mctp
526 );
527
528 assert_eq!(
530 SmbusCommandCode::try_from_bits(0x100),
531 Err("Command code out of range")
532 );
533
534 assert_eq!(
536 SmbusCommandCode::try_from_bits(0x10),
537 Err("Invalid command code")
538 );
539
540 assert_eq!(SmbusCommandCode::Mctp.try_into_bits().unwrap(), 0x0F);
542 }
543
544 #[test]
545 fn test_header_bit_register_edge_cases() {
546 let header = SmbusEspiMediumHeader::default();
548 assert_eq!(header.destination_slave_address, 0);
549 assert_eq!(header.source_slave_address, 0);
550 assert_eq!(header.byte_count, 0);
551 assert_eq!(header.command_code, SmbusCommandCode::Mctp); let header = SmbusEspiMediumHeader {
555 destination_slave_address: 0x7F, source_slave_address: 0x3F, byte_count: 0xFF, command_code: SmbusCommandCode::Mctp,
559 ..Default::default()
560 };
561
562 let header_value: u32 = header.try_into().unwrap();
564 let reconstructed = SmbusEspiMediumHeader::try_from(header_value).unwrap();
565 assert_eq!(reconstructed, header);
566 }
567
568 #[test]
569 fn test_pec_calculation_accuracy() {
570 let medium = SmbusEspiMedium;
571 let reply_context = SmbusEspiReplyContext {
572 destination_slave_address: 0x50,
573 source_slave_address: 0x30,
574 };
575
576 let test_data = [0x01, 0x02, 0x03];
578 let mut buffer = [0u8; 32];
579
580 let result = medium
581 .serialize(reply_context, &mut buffer, |buf| {
582 buf[..test_data.len()].copy_from_slice(&test_data);
583 Ok(test_data.len())
584 })
585 .unwrap();
586
587 let data_for_pec = &result[0..result.len() - 1];
589 let expected_pec = smbus_pec::pec(data_for_pec);
590 let actual_pec = result[result.len() - 1];
591
592 assert_eq!(actual_pec, expected_pec);
593 }
594
595 #[test]
596 fn test_serialize_with_empty_payload() {
597 let medium = SmbusEspiMedium;
598 let reply_context = SmbusEspiReplyContext {
599 destination_slave_address: 0x60,
600 source_slave_address: 0x70,
601 };
602
603 let mut buffer = [0u8; 16];
604
605 let result = medium
606 .serialize(
607 reply_context,
608 &mut buffer,
609 |_| Ok(0), )
611 .unwrap();
612
613 assert_eq!(result.len(), 5); let header_value = u32::from_be_bytes([result[0], result[1], result[2], result[3]]);
617 let header = SmbusEspiMediumHeader::try_from(header_value).unwrap();
618 assert_eq!(header.byte_count, 0);
619 assert_eq!(header.destination_slave_address, 0x70); assert_eq!(header.source_slave_address, 0x60); let expected_pec = smbus_pec::pec(&result[0..4]);
624 assert_eq!(result[4], expected_pec);
625 }
626
627 #[test]
628 fn test_max_message_body_size() {
629 let medium = SmbusEspiMedium;
630 assert_eq!(medium.max_message_body_size(), 32);
631 }
632
633 #[test]
634 fn test_address_swapping_in_reply_context() {
635 let original_frame = SmbusEspiMediumFrame {
637 header: SmbusEspiMediumHeader {
638 destination_slave_address: 0x2A, source_slave_address: 0x3B, ..Default::default()
641 },
642 pec: 0,
643 };
644
645 let reply_context = SmbusEspiReplyContext::new(original_frame);
646 assert_eq!(reply_context.destination_slave_address, 0x2A);
647 assert_eq!(reply_context.source_slave_address, 0x3B);
648
649 let medium = SmbusEspiMedium;
651 let mut buffer = [0u8; 16];
652
653 let result = medium
654 .serialize(reply_context, &mut buffer, |_| Ok(0))
655 .unwrap();
656
657 let header_value = u32::from_be_bytes([result[0], result[1], result[2], result[3]]);
658 let response_header = SmbusEspiMediumHeader::try_from(header_value).unwrap();
659
660 assert_eq!(response_header.destination_slave_address, 0x3B);
662 assert_eq!(response_header.source_slave_address, 0x2A);
663 }
664
665 #[test]
666 fn test_deserialize_with_different_byte_counts() {
667 let medium = SmbusEspiMedium;
668
669 for byte_count in [1, 16, 32, 64, 128, 255] {
670 let header_bytes = [
671 0x20, 0x0F, byte_count, 0x21, ];
676
677 let payload = [0x42u8; 255];
678 let payload_slice = &payload[..byte_count as usize];
679
680 let mut combined = [0u8; 259]; combined[0..4].copy_from_slice(&header_bytes);
682 combined[4..4 + byte_count as usize].copy_from_slice(payload_slice);
683 let pec = smbus_pec::pec(&combined[0..4 + byte_count as usize]);
684
685 let mut packet = [0u8; 260]; packet[0..4].copy_from_slice(&header_bytes);
687 packet[4..4 + byte_count as usize].copy_from_slice(payload_slice);
688 packet[4 + byte_count as usize] = pec;
689
690 let packet_slice = &packet[0..4 + byte_count as usize + 1];
691 let result = medium.deserialize(packet_slice).unwrap();
692 let (frame, body) = result;
693
694 assert_eq!(frame.header.byte_count, byte_count);
695 assert_eq!(body.len(), byte_count as usize);
696 assert_eq!(frame.pec, pec);
697 }
698 }
699
700 #[test]
701 fn test_smbus_buffer_overflow_protection() {
702 let medium = SmbusEspiMedium;
703
704 let header_bytes = [
706 0x20, 0x0F, 0xFF, 0x21, ];
711
712 let short_payload = [0xAA, 0xBB]; let mut packet = [0u8; 7]; packet[0..4].copy_from_slice(&header_bytes);
716 packet[4..6].copy_from_slice(&short_payload);
717 packet[6] = 0x00; let result = medium.deserialize(&packet);
720 assert_eq!(
721 result,
722 Err(MctpPacketError::MediumError(
723 "Packet too short to parse smbus body and PEC"
724 ))
725 );
726 }
727
728 #[test]
729 fn test_smbus_serialize_buffer_underflow() {
730 let medium = SmbusEspiMedium;
731 let reply_context = SmbusEspiReplyContext {
732 destination_slave_address: 0x20,
733 source_slave_address: 0x10,
734 };
735
736 let mut tiny_buffer = [0u8; 4]; let result = medium.serialize(reply_context, &mut tiny_buffer, |_| {
740 Ok(0) });
742
743 assert_eq!(
744 result,
745 Err(MctpPacketError::MediumError(
746 "Buffer too small for smbus frame"
747 ))
748 );
749 }
750
751 #[test]
752 fn test_smbus_header_bounds_checking() {
753 let medium = SmbusEspiMedium;
754
755 for packet_size in 0..4 {
757 let short_packet = [0u8; 4];
758 let result = medium.deserialize(&short_packet[..packet_size]);
759 assert_eq!(
760 result,
761 Err(MctpPacketError::MediumError(
762 "Packet too short to parse smbus header"
763 ))
764 );
765 }
766 }
767
768 #[test]
769 fn test_smbus_pec_bounds_checking() {
770 let medium = SmbusEspiMedium;
771
772 let header_bytes = [
774 0x20, 0x0F, 0x05, 0x21, ];
779
780 let payload = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE]; let mut packet = [0u8; 9]; packet[0..4].copy_from_slice(&header_bytes);
784 packet[4..9].copy_from_slice(&payload);
785
786 let result = medium.deserialize(&packet);
787 assert_eq!(
788 result,
789 Err(MctpPacketError::MediumError(
790 "Packet too short to parse smbus body and PEC"
791 ))
792 );
793 }
794
795 #[test]
796 fn test_smbus_zero_byte_count_edge_case() {
797 let medium = SmbusEspiMedium;
798
799 let header_bytes = [
801 0x20, 0x0F, 0x00, 0x21, ];
806
807 let mut short_packet = [0u8; 4]; short_packet.copy_from_slice(&header_bytes);
810
811 let result = medium.deserialize(&short_packet);
812 assert_eq!(
813 result,
814 Err(MctpPacketError::MediumError(
815 "Packet too short to parse smbus body and PEC"
816 ))
817 );
818 }
819
820 #[test]
821 fn test_smbus_maximum_payload_boundary() {
822 let medium = SmbusEspiMedium;
823
824 let reply_context = SmbusEspiReplyContext {
826 destination_slave_address: 0x20,
827 source_slave_address: 0x10,
828 };
829
830 let max_payload = [0x55u8; 255];
831 let mut buffer = [0u8; 260]; let result = medium.serialize(reply_context, &mut buffer, |buf| {
834 let copy_len = max_payload.len().min(buf.len());
835 buf[..copy_len].copy_from_slice(&max_payload[..copy_len]);
836 Ok(copy_len)
837 });
838
839 assert!(result.is_ok());
840 let serialized = result.unwrap();
841 assert_eq!(serialized.len(), 260); let mut small_buffer = [0u8; 259]; let result_small = medium.serialize(reply_context, &mut small_buffer, |buf| {
846 let copy_len = max_payload.len().min(buf.len());
848 buf[..copy_len].copy_from_slice(&max_payload[..copy_len]);
849 Ok(copy_len)
850 });
851
852 assert!(result_small.is_ok());
854 let serialized_small = result_small.unwrap();
855 assert_eq!(serialized_small.len(), 259); }
857}