1use hex;
2use std::fmt;
3use std::io::prelude::*;
4use std::io::Cursor;
5use std::str;
6use std::time::SystemTime;
7
8use byteorder::{BigEndian, ReadBytesExt};
9use bytes::{BufMut, BytesMut};
10use chrono::{DateTime, TimeZone, Utc};
11
12use super::oer::{self, BufOerExt, MutBufOerExt};
13use super::{Address, ErrorCode, ParseError};
14use std::convert::TryFrom;
15
16const AMOUNT_LEN: usize = 8;
17const EXPIRY_LEN: usize = 17;
18const CONDITION_LEN: usize = 32;
19const FULFILLMENT_LEN: usize = 32;
20const ERROR_CODE_LEN: usize = 3;
21
22static INTERLEDGER_TIMESTAMP_FORMAT: &str = "%Y%m%d%H%M%S%3f";
23
24#[derive(Clone, Copy, Debug, PartialEq)]
25#[repr(u8)]
26pub enum PacketType {
27 Prepare = 12,
28 Fulfill = 13,
29 Reject = 14,
30}
31
32impl TryFrom<&[u8]> for PacketType {
34 type Error = ParseError;
35
36 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
37 match bytes.first() {
38 Some(&12) => Ok(PacketType::Prepare),
39 Some(&13) => Ok(PacketType::Fulfill),
40 Some(&14) => Ok(PacketType::Reject),
41 _ => Err(ParseError::InvalidPacket(format!(
42 "Unknown packet type: {:?}",
43 bytes,
44 ))),
45 }
46 }
47}
48
49impl TryFrom<u8> for PacketType {
50 type Error = ParseError;
51
52 fn try_from(byte: u8) -> Result<Self, Self::Error> {
53 match byte {
54 12 => Ok(PacketType::Prepare),
55 13 => Ok(PacketType::Fulfill),
56 14 => Ok(PacketType::Reject),
57 _ => Err(ParseError::InvalidPacket(format!(
58 "Unknown packet type: {:?}",
59 byte,
60 ))),
61 }
62 }
63}
64
65#[derive(Debug, PartialEq, Clone)]
66pub enum Packet {
67 Prepare(Prepare),
68 Fulfill(Fulfill),
69 Reject(Reject),
70}
71
72impl TryFrom<BytesMut> for Packet {
73 type Error = ParseError;
74
75 fn try_from(buffer: BytesMut) -> Result<Self, Self::Error> {
76 match buffer.first() {
77 Some(&12) => Ok(Packet::Prepare(Prepare::try_from(buffer)?)),
78 Some(&13) => Ok(Packet::Fulfill(Fulfill::try_from(buffer)?)),
79 Some(&14) => Ok(Packet::Reject(Reject::try_from(buffer)?)),
80 _ => Err(ParseError::InvalidPacket(format!(
81 "Unknown packet type: {:?}",
82 buffer.first(),
83 ))),
84 }
85 }
86}
87
88impl From<Packet> for BytesMut {
89 fn from(packet: Packet) -> Self {
90 match packet {
91 Packet::Prepare(prepare) => prepare.into(),
92 Packet::Fulfill(fulfill) => fulfill.into(),
93 Packet::Reject(reject) => reject.into(),
94 }
95 }
96}
97
98impl From<Prepare> for Packet {
99 fn from(prepare: Prepare) -> Self {
100 Packet::Prepare(prepare)
101 }
102}
103
104impl From<Fulfill> for Packet {
105 fn from(fulfill: Fulfill) -> Self {
106 Packet::Fulfill(fulfill)
107 }
108}
109
110impl From<Reject> for Packet {
111 fn from(reject: Reject) -> Self {
112 Packet::Reject(reject)
113 }
114}
115
116#[derive(PartialEq, Clone)]
117pub struct Prepare {
118 buffer: BytesMut,
119 content_offset: usize,
120 destination: Address,
121 amount: u64,
122 expires_at: SystemTime,
123 data_offset: usize,
124}
125
126#[derive(Clone, Debug, PartialEq)]
127pub struct PrepareBuilder<'a> {
128 pub amount: u64,
129 pub expires_at: SystemTime,
130 pub execution_condition: &'a [u8; 32],
131 pub destination: Address,
132 pub data: &'a [u8],
133}
134
135impl TryFrom<BytesMut> for Prepare {
136 type Error = ParseError;
137
138 fn try_from(buffer: BytesMut) -> Result<Self, Self::Error> {
139 let (content_offset, mut content) = deserialize_envelope(PacketType::Prepare, &buffer)?;
140 let content_len = content.len();
141 let amount = content.read_u64::<BigEndian>()?;
142
143 let mut expires_at = [0x00; 17];
144 content.read_exact(&mut expires_at)?;
145 let expires_at = str::from_utf8(&expires_at[..])?;
146 let expires_at: DateTime<Utc> =
147 Utc.datetime_from_str(&expires_at, INTERLEDGER_TIMESTAMP_FORMAT)?;
148 let expires_at = SystemTime::from(expires_at);
149
150 content.skip(CONDITION_LEN)?;
152
153 let destination = Address::try_from(content.read_var_octet_string()?)?;
154
155 let data_offset = content_offset + content_len - content.len();
157 content.skip_var_octet_string()?;
158
159 Ok(Prepare {
160 buffer,
161 content_offset,
162 destination,
163 amount,
164 expires_at,
165 data_offset,
166 })
167 }
168}
169
170impl Prepare {
171 #[inline]
172 pub fn amount(&self) -> u64 {
173 self.amount
174 }
175
176 #[inline]
177 pub fn set_amount(&mut self, amount: u64) {
178 self.amount = amount;
179 let mut cursor = Cursor::new(&mut self.buffer);
180 cursor.set_position(self.content_offset as u64);
181 cursor.put_u64_be(amount);
182 }
183
184 #[inline]
185 pub fn expires_at(&self) -> SystemTime {
186 self.expires_at
187 }
188
189 #[inline]
190 pub fn set_expires_at(&mut self, expires_at: SystemTime) {
191 self.expires_at = expires_at;
192 let offset = self.content_offset + AMOUNT_LEN;
193 write!(
194 &mut self.buffer[offset..],
195 "{}",
196 DateTime::<Utc>::from(expires_at).format(INTERLEDGER_TIMESTAMP_FORMAT),
197 )
198 .unwrap();
199 }
200
201 #[inline]
203 pub fn execution_condition(&self) -> &[u8] {
204 let begin = self.content_offset + AMOUNT_LEN + EXPIRY_LEN;
205 let end = begin + CONDITION_LEN;
206 &self.buffer[begin..end]
207 }
208
209 #[inline]
210 pub fn destination(&self) -> Address {
211 self.destination.clone()
212 }
213
214 #[inline]
215 pub fn data(&self) -> &[u8] {
216 (&self.buffer[self.data_offset..])
217 .peek_var_octet_string()
218 .unwrap()
219 }
220
221 #[inline]
222 pub fn into_data(mut self) -> BytesMut {
223 oer::extract_var_octet_string(self.buffer.split_off(self.data_offset)).unwrap()
224 }
225}
226
227impl AsRef<[u8]> for Prepare {
228 #[inline]
229 fn as_ref(&self) -> &[u8] {
230 &self.buffer
231 }
232}
233
234impl From<Prepare> for BytesMut {
235 fn from(prepare: Prepare) -> Self {
236 prepare.buffer
237 }
238}
239
240impl fmt::Debug for Prepare {
241 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
242 formatter
243 .debug_struct("Prepare")
244 .field("destination", &self.destination())
245 .field("amount", &self.amount())
246 .field(
247 "expires_at",
248 &DateTime::<Utc>::from(self.expires_at()).to_rfc3339(),
249 )
250 .field(
251 "execution_condition",
252 &hex::encode(self.execution_condition()),
253 )
254 .field("data_length", &self.data().len())
255 .finish()
256 }
257}
258
259impl<'a> PrepareBuilder<'a> {
260 pub fn build(&self) -> Prepare {
261 const STATIC_LEN: usize = AMOUNT_LEN + EXPIRY_LEN + CONDITION_LEN;
262 let destination_size = oer::predict_var_octet_string(self.destination.len());
263 let data_size = oer::predict_var_octet_string(self.data.len());
264 let content_len = STATIC_LEN + destination_size + data_size;
265 let buf_size = 1 + oer::predict_var_octet_string(content_len);
266 let mut buffer = BytesMut::with_capacity(buf_size);
267
268 buffer.put_u8(PacketType::Prepare as u8);
269 buffer.put_var_octet_string_length(content_len);
270 let content_offset = buffer.len();
271 buffer.put_u64_be(self.amount);
272
273 let mut writer = buffer.writer();
274 write!(
275 writer,
276 "{}",
277 DateTime::<Utc>::from(self.expires_at).format(INTERLEDGER_TIMESTAMP_FORMAT),
278 )
279 .unwrap();
280 let mut buffer = writer.into_inner();
281
282 buffer.put_slice(&self.execution_condition[..]);
283 buffer.put_var_octet_string::<&[u8]>(self.destination.as_ref());
284 buffer.put_var_octet_string(self.data);
285
286 Prepare {
287 buffer,
288 content_offset,
289 destination: self.destination.clone(),
290 amount: self.amount,
291 expires_at: self.expires_at,
292 data_offset: buf_size - data_size,
293 }
294 }
295}
296
297#[derive(PartialEq, Clone)]
298pub struct Fulfill {
299 buffer: BytesMut,
300 content_offset: usize,
301}
302
303#[derive(Clone, Debug, PartialEq)]
304pub struct FulfillBuilder<'a> {
305 pub fulfillment: &'a [u8; 32],
306 pub data: &'a [u8],
307}
308
309impl TryFrom<BytesMut> for Fulfill {
310 type Error = ParseError;
311
312 fn try_from(buffer: BytesMut) -> Result<Self, Self::Error> {
313 let (content_offset, mut content) = deserialize_envelope(PacketType::Fulfill, &buffer)?;
314
315 content.skip(FULFILLMENT_LEN)?;
316 content.skip_var_octet_string()?;
317
318 Ok(Fulfill {
319 buffer,
320 content_offset,
321 })
322 }
323}
324
325impl Fulfill {
326 #[inline]
328 pub fn fulfillment(&self) -> &[u8] {
329 let begin = self.content_offset;
330 let end = begin + FULFILLMENT_LEN;
331 &self.buffer[begin..end]
332 }
333
334 #[inline]
335 pub fn data(&self) -> &[u8] {
336 let data_offset = self.content_offset + FULFILLMENT_LEN;
337 (&self.buffer[data_offset..])
338 .peek_var_octet_string()
339 .unwrap()
340 }
341
342 #[inline]
343 pub fn into_data(mut self) -> BytesMut {
344 let data_offset = self.content_offset + FULFILLMENT_LEN;
345 oer::extract_var_octet_string(self.buffer.split_off(data_offset)).unwrap()
346 }
347}
348
349impl AsRef<[u8]> for Fulfill {
350 #[inline]
351 fn as_ref(&self) -> &[u8] {
352 &self.buffer
353 }
354}
355
356impl From<Fulfill> for BytesMut {
357 fn from(fulfill: Fulfill) -> Self {
358 fulfill.buffer
359 }
360}
361
362impl fmt::Debug for Fulfill {
363 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
364 formatter
365 .debug_struct("Fulfill")
366 .field("fulfillment", &hex::encode(self.fulfillment()))
367 .field("data_length", &self.data().len())
368 .finish()
369 }
370}
371
372impl<'a> FulfillBuilder<'a> {
373 pub fn build(&self) -> Fulfill {
374 let data_size = oer::predict_var_octet_string(self.data.len());
375 let content_len = FULFILLMENT_LEN + data_size;
376 let buf_size = 1 + oer::predict_var_octet_string(content_len);
377 let mut buffer = BytesMut::with_capacity(buf_size);
378
379 buffer.put_u8(PacketType::Fulfill as u8);
380 buffer.put_var_octet_string_length(content_len);
381 let content_offset = buffer.len();
382 buffer.put_slice(&self.fulfillment[..]);
383 buffer.put_var_octet_string(&self.data[..]);
384 Fulfill {
385 buffer,
386 content_offset,
387 }
388 }
389}
390
391#[derive(PartialEq, Clone)]
392pub struct Reject {
393 buffer: BytesMut,
394 code: ErrorCode,
395 message_offset: usize,
396 triggered_by_offset: usize,
397 data_offset: usize,
398}
399
400#[derive(Clone, Debug, PartialEq)]
401pub struct RejectBuilder<'a> {
402 pub code: ErrorCode,
403 pub message: &'a [u8],
404 pub triggered_by: Option<&'a Address>,
405 pub data: &'a [u8],
406}
407
408impl TryFrom<BytesMut> for Reject {
409 type Error = ParseError;
410
411 fn try_from(buffer: BytesMut) -> Result<Self, Self::Error> {
412 let (content_offset, mut content) = deserialize_envelope(PacketType::Reject, &buffer)?;
413 let content_len = content.len();
414
415 let mut code = [0; 3];
416 content.read_exact(&mut code)?;
417 let code = ErrorCode::new(code);
418
419 let triggered_by_offset = content_offset + content_len - content.len();
420 Address::try_from(content.read_var_octet_string()?)?;
421
422 let message_offset = content_offset + content_len - content.len();
423 content.skip_var_octet_string()?;
424
425 let data_offset = content_offset + content_len - content.len();
426 content.skip_var_octet_string()?;
427
428 Ok(Reject {
429 buffer,
430 code,
431 triggered_by_offset,
432 message_offset,
433 data_offset,
434 })
435 }
436}
437
438impl Reject {
439 #[inline]
440 pub fn code(&self) -> ErrorCode {
441 self.code
442 }
443
444 #[inline]
445 pub fn triggered_by(&self) -> Option<Address> {
446 match (&self.buffer[self.triggered_by_offset..]).peek_var_octet_string() {
447 Ok(bytes) => Address::try_from(bytes).ok(),
448 Err(_) => None,
449 }
450 }
451
452 #[inline]
453 pub fn message(&self) -> &[u8] {
454 (&self.buffer[self.message_offset..])
455 .peek_var_octet_string()
456 .unwrap()
457 }
458
459 #[inline]
460 pub fn data(&self) -> &[u8] {
461 (&self.buffer[self.data_offset..])
462 .peek_var_octet_string()
463 .unwrap()
464 }
465
466 pub fn into_data(mut self) -> BytesMut {
467 oer::extract_var_octet_string(self.buffer.split_off(self.data_offset)).unwrap()
468 }
469}
470
471impl AsRef<[u8]> for Reject {
472 #[inline]
473 fn as_ref(&self) -> &[u8] {
474 &self.buffer
475 }
476}
477
478impl From<Reject> for BytesMut {
479 fn from(reject: Reject) -> Self {
480 reject.buffer
481 }
482}
483
484impl fmt::Debug for Reject {
485 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
486 formatter
487 .debug_struct("Reject")
488 .field("code", &self.code())
489 .field(
490 "message",
491 &str::from_utf8(self.message()).map_err(|_| fmt::Error)?,
492 )
493 .field("triggered_by", &self.triggered_by())
494 .field("data_length", &self.data().len())
495 .finish()
496 }
497}
498
499impl<'a> RejectBuilder<'a> {
500 pub fn build(&self) -> Reject {
501 let (trigerred_by_message, len) = match self.triggered_by {
502 Some(ref msg) => (msg.as_ref(), msg.len()),
503 None => {
504 let empty_msg: &[u8] = &[];
505 (empty_msg, 0)
506 }
507 };
508 let triggered_by_size = oer::predict_var_octet_string(len);
509 let message_size = oer::predict_var_octet_string(self.message.len());
510 let data_size = oer::predict_var_octet_string(self.data.len());
511 let content_len = ERROR_CODE_LEN + triggered_by_size + message_size + data_size;
512 let buf_size = 1 + oer::predict_var_octet_string(content_len);
513 let mut buffer = BytesMut::with_capacity(buf_size);
514
515 buffer.put_u8(PacketType::Reject as u8);
516 buffer.put_var_octet_string_length(content_len);
517 buffer.put_slice(&<[u8; 3]>::from(self.code)[..]);
518 buffer.put_var_octet_string::<&[u8]>(trigerred_by_message);
519 buffer.put_var_octet_string(self.message);
520 buffer.put_var_octet_string(self.data);
521 Reject {
522 buffer,
523 code: self.code,
524 triggered_by_offset: buf_size - data_size - message_size - triggered_by_size,
525 message_offset: buf_size - data_size - message_size,
526 data_offset: buf_size - data_size,
527 }
528 }
529}
530
531fn deserialize_envelope(
532 packet_type: PacketType,
533 mut reader: &[u8],
534) -> Result<(usize, &[u8]), ParseError> {
535 let got_type = reader.read_u8()?;
536 if got_type == packet_type as u8 {
537 let content_offset = 1 + {
538 let mut peek = &reader[..];
540 let before = peek.len();
541 peek.read_var_octet_string_length()?;
542 before - peek.len()
543 };
544 let content = reader.peek_var_octet_string()?;
545 Ok((content_offset, content))
546 } else {
547 Err(ParseError::InvalidPacket(format!(
548 "Unexpected packet type: {:?}",
549 got_type,
550 )))
551 }
552}
553
554#[derive(Clone, Debug, PartialEq)]
555pub struct MaxPacketAmountDetails {
556 amount_received: u64,
557 max_amount: u64,
558}
559
560impl MaxPacketAmountDetails {
561 #[inline]
562 pub fn new(amount_received: u64, max_amount: u64) -> Self {
563 MaxPacketAmountDetails {
564 amount_received,
565 max_amount,
566 }
567 }
568
569 pub fn from_bytes(mut bytes: &[u8]) -> Result<Self, std::io::Error> {
571 let amount_received = bytes.read_u64::<BigEndian>()?;
572 let max_amount = bytes.read_u64::<BigEndian>()?;
573 Ok(MaxPacketAmountDetails::new(amount_received, max_amount))
574 }
575
576 pub fn to_bytes(&self) -> [u8; 16] {
577 let mut bytes = [0x00_u8; 16];
578 let mut writer = Cursor::new(&mut bytes[..]);
579 writer.put_u64_be(self.amount_received);
580 writer.put_u64_be(self.max_amount);
581 bytes
582 }
583
584 #[inline]
585 pub fn amount_received(&self) -> u64 {
586 self.amount_received
587 }
588
589 #[inline]
590 pub fn max_amount(&self) -> u64 {
591 self.max_amount
592 }
593}
594
595#[cfg(test)]
596mod test_packet_type {
597 use super::*;
598
599 #[test]
600 fn test_try_from() {
601 assert_eq!(PacketType::try_from(12).unwrap(), PacketType::Prepare);
602 assert_eq!(PacketType::try_from(13).unwrap(), PacketType::Fulfill);
603 assert_eq!(PacketType::try_from(14).unwrap(), PacketType::Reject);
604 assert!(PacketType::try_from(15).is_err());
605 }
606}
607
608#[cfg(test)]
609mod test_packet {
610 use super::*;
611 use crate::fixtures::{FULFILL, PREPARE, REJECT};
612 use crate::fixtures::{FULFILL_BYTES, PREPARE_BYTES, REJECT_BYTES};
613
614 #[test]
615 fn test_try_from() {
616 assert_eq!(
617 Packet::try_from(BytesMut::from(PREPARE_BYTES)).unwrap(),
618 Packet::Prepare(PREPARE.clone()),
619 );
620 assert_eq!(
621 Packet::try_from(BytesMut::from(FULFILL_BYTES)).unwrap(),
622 Packet::Fulfill(FULFILL.clone()),
623 );
624 assert_eq!(
625 Packet::try_from(BytesMut::from(REJECT_BYTES)).unwrap(),
626 Packet::Reject(REJECT.clone()),
627 );
628
629 assert!(Packet::try_from(BytesMut::from(vec![])).is_err());
631 assert!(Packet::try_from(BytesMut::from(vec![0x99])).is_err());
633 }
634
635 #[test]
636 fn test_into_bytes_mut() {
637 assert_eq!(
638 BytesMut::from(Packet::Prepare(PREPARE.clone())),
639 BytesMut::from(PREPARE_BYTES),
640 );
641 assert_eq!(
642 BytesMut::from(Packet::Fulfill(FULFILL.clone())),
643 BytesMut::from(FULFILL_BYTES),
644 );
645 assert_eq!(
646 BytesMut::from(Packet::Reject(REJECT.clone())),
647 BytesMut::from(REJECT_BYTES),
648 );
649 }
650}
651
652#[cfg(test)]
653mod test_prepare {
654 use super::*;
655 use crate::fixtures::{self, PREPARE, PREPARE_BUILDER, PREPARE_BYTES};
656
657 #[test]
658 fn test_invalid_address() {
659 let mut prep = BytesMut::from(PREPARE_BYTES);
660 prep[67] = 42; assert!(Prepare::try_from(prep).is_err());
662 }
663
664 #[test]
665 fn test_try_from() {
666 assert_eq!(
667 Prepare::try_from(BytesMut::from(PREPARE_BYTES)).unwrap(),
668 *PREPARE
669 );
670
671 assert!(Prepare::try_from({
673 let mut with_wrong_type = BytesMut::from(PREPARE_BYTES);
674 with_wrong_type[0] = PacketType::Fulfill as u8;
675 with_wrong_type
676 })
677 .is_err());
678
679 let with_junk_data = Prepare::try_from({
681 let mut buffer = BytesMut::from(PREPARE_BYTES);
682 buffer.extend_from_slice(&[0x11, 0x12, 0x13]);
683 buffer
684 })
685 .unwrap();
686 assert_eq!(with_junk_data.amount(), PREPARE.amount());
687 assert_eq!(with_junk_data.expires_at(), *fixtures::EXPIRES_AT);
688 assert_eq!(
689 with_junk_data.execution_condition(),
690 fixtures::EXECUTION_CONDITION
691 );
692 assert_eq!(with_junk_data.destination(), PREPARE.destination());
693 assert_eq!(with_junk_data.data(), fixtures::DATA);
694 }
695
696 #[test]
697 fn test_into_bytes_mut() {
698 assert_eq!(BytesMut::from(PREPARE.clone()), PREPARE_BYTES);
699 }
700
701 #[test]
702 fn test_amount() {
703 assert_eq!(PREPARE.amount(), PREPARE_BUILDER.amount);
704 }
705
706 #[test]
707 fn test_set_amount() {
708 let target_amount = PREPARE_BUILDER.amount;
709 let destination = PREPARE_BUILDER.destination.clone();
710 let mut prepare = PrepareBuilder {
711 amount: 9999,
712 destination,
713 ..*PREPARE_BUILDER
714 }
715 .build();
716 prepare.set_amount(target_amount);
717 assert_eq!(prepare.amount(), target_amount);
718 assert_eq!(BytesMut::from(prepare), PREPARE_BYTES);
719 }
720
721 #[test]
722 fn test_expires_at() {
723 assert_eq!(PREPARE.expires_at(), *fixtures::EXPIRES_AT);
724 }
725
726 #[test]
727 fn test_set_expires_at() {
728 let target_expiry = PREPARE_BUILDER.expires_at;
729 let destination = PREPARE_BUILDER.destination.clone();
730 let mut prepare = PrepareBuilder {
731 expires_at: SystemTime::now(),
732 destination,
733 ..*PREPARE_BUILDER
734 }
735 .build();
736 prepare.set_expires_at(target_expiry);
737 assert_eq!(prepare.expires_at(), target_expiry);
738 assert_eq!(BytesMut::from(prepare), PREPARE_BYTES);
739 }
740
741 #[test]
742 fn test_execution_condition() {
743 assert_eq!(PREPARE.execution_condition(), fixtures::EXECUTION_CONDITION,);
744 }
745
746 #[test]
747 fn test_data() {
748 assert_eq!(PREPARE.data(), fixtures::DATA);
749 }
750
751 #[test]
752 fn test_into_data() {
753 assert_eq!(PREPARE.clone().into_data(), BytesMut::from(PREPARE.data()),);
754 }
755}
756
757#[cfg(test)]
758mod test_fulfill {
759 use super::*;
760 use crate::fixtures::{self, FULFILL, FULFILL_BYTES};
761
762 #[test]
763 fn test_try_from() {
764 assert_eq!(
765 Fulfill::try_from(BytesMut::from(FULFILL_BYTES)).unwrap(),
766 *FULFILL
767 );
768
769 let with_junk_data = Fulfill::try_from({
771 let mut buffer = BytesMut::from(FULFILL_BYTES);
772 buffer.extend_from_slice(&[0x11, 0x12, 0x13]);
773 buffer
774 })
775 .unwrap();
776 assert_eq!(with_junk_data.fulfillment(), fixtures::FULFILLMENT);
777 assert_eq!(with_junk_data.data(), fixtures::DATA);
778
779 let with_data_in_junk = {
782 let mut buffer = BytesMut::with_capacity(1024);
783 buffer.put_u8(PacketType::Fulfill as u8);
784 buffer.put_var_octet_string_length(32);
785 buffer.put_slice(&fixtures::FULFILLMENT[..]);
786 buffer.put_var_octet_string(fixtures::DATA);
787 buffer
788 };
789 assert!(Fulfill::try_from(with_data_in_junk).is_err());
790 }
791
792 #[test]
793 fn test_into_bytes_mut() {
794 assert_eq!(BytesMut::from(FULFILL.clone()), FULFILL_BYTES);
795 }
796
797 #[test]
798 fn test_fulfillment() {
799 assert_eq!(FULFILL.fulfillment(), fixtures::FULFILLMENT);
800 }
801
802 #[test]
803 fn test_data() {
804 assert_eq!(FULFILL.data(), fixtures::DATA);
805 }
806
807 #[test]
808 fn test_into_data() {
809 assert_eq!(FULFILL.clone().into_data(), BytesMut::from(FULFILL.data()),);
810 }
811}
812
813#[cfg(test)]
814mod test_reject {
815 use super::*;
816 use crate::fixtures::{self, REJECT, REJECT_BUILDER, REJECT_BYTES};
817
818 #[test]
819 fn test_try_from() {
820 assert_eq!(
821 Reject::try_from(BytesMut::from(REJECT_BYTES)).unwrap(),
822 *REJECT,
823 );
824
825 let with_junk_data = Reject::try_from({
827 let mut buffer = BytesMut::from(REJECT_BYTES);
828 buffer.extend_from_slice(&[0x11, 0x12, 0x13]);
829 buffer
830 })
831 .unwrap();
832 assert_eq!(with_junk_data.code(), REJECT_BUILDER.code);
833 assert_eq!(with_junk_data.message(), REJECT_BUILDER.message);
834 assert_eq!(
835 with_junk_data.triggered_by().as_ref(),
836 REJECT_BUILDER.triggered_by
837 );
838 assert_eq!(with_junk_data.data(), fixtures::DATA);
839 }
840
841 #[test]
842 fn test_into_bytes_mut() {
843 assert_eq!(BytesMut::from(REJECT.clone()), REJECT_BYTES);
844 }
845
846 #[test]
847 fn test_code() {
848 assert_eq!(REJECT.code(), REJECT_BUILDER.code);
849 }
850
851 #[test]
852 fn test_message() {
853 assert_eq!(REJECT.message(), REJECT_BUILDER.message);
854 }
855
856 #[test]
857 fn test_triggered_by() {
858 assert_eq!(REJECT.triggered_by().as_ref(), REJECT_BUILDER.triggered_by);
859 }
860
861 #[test]
862 fn test_data() {
863 assert_eq!(REJECT.data(), fixtures::DATA);
864 }
865
866 #[test]
867 fn test_into_data() {
868 assert_eq!(REJECT.clone().into_data(), BytesMut::from(REJECT.data()));
869 }
870}
871
872#[cfg(test)]
873mod test_max_packet_amount_details {
874 use super::*;
875
876 static BYTES: &[u8] = b"\
877 \x00\x00\x00\x00\x00\x03\x02\x01\
878 \x00\x00\x00\x00\x00\x06\x05\x04\
879 ";
880
881 static DETAILS: MaxPacketAmountDetails = MaxPacketAmountDetails {
882 amount_received: 0x0003_0201,
883 max_amount: 0x0006_0504,
884 };
885
886 #[test]
887 fn test_from_bytes() {
888 assert_eq!(MaxPacketAmountDetails::from_bytes(&BYTES).unwrap(), DETAILS,);
889 assert_eq!(
890 MaxPacketAmountDetails::from_bytes(&[][..])
891 .unwrap_err()
892 .kind(),
893 std::io::ErrorKind::UnexpectedEof,
894 );
895 }
896
897 #[test]
898 fn test_to_bytes() {
899 assert_eq!(&DETAILS.to_bytes()[..], BYTES);
900 }
901
902 #[test]
903 fn test_amount_received() {
904 assert_eq!(DETAILS.amount_received(), 0x0003_0201);
905 }
906
907 #[test]
908 fn test_max_amount() {
909 assert_eq!(DETAILS.max_amount(), 0x0006_0504);
910 }
911}