Isabelle's Lazy Message Protocol
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

101 linhas
2.4 KiB

  1. //! # Isabelle's Lazy Message Protocol
  2. #![allow(dead_code)]
  3. use futures_util::io::{AsyncReadExt, AsyncWriteExt};
  4. use std::convert::TryInto;
  5. use std::marker::Unpin;
  6. mod message;
  7. pub use message::Message;
  8. /// lazy error
  9. pub type Error = Box<dyn std::error::Error>;
  10. /// lazy result
  11. pub type Result<T> = std::result::Result<T, Error>;
  12. struct NetworkPacket(Vec<u8>);
  13. /// A type of data that can be sent
  14. pub trait Sendable: Sized {
  15. fn to_packet(self) -> Result<Packet>;
  16. fn from_packet(packet: Packet) -> Result<Self>;
  17. }
  18. /// Data to be sent
  19. pub struct Packet {
  20. kind: PacketKind,
  21. contents: Vec<u8>,
  22. }
  23. impl Packet {
  24. /// Create a new `Packet`
  25. pub fn new(kind: PacketKind, contents: Vec<u8>) -> Packet {
  26. Packet { kind, contents }
  27. }
  28. fn to_network_packet(self) -> NetworkPacket {
  29. let mut contents: Vec<u8> = Vec::new();
  30. // write packet kind byte
  31. contents.push(self.kind as u8);
  32. // write the packet length
  33. let contents_length = self.contents.len() as u32;
  34. contents.extend_from_slice(&contents_length.to_le_bytes());
  35. // write contents
  36. contents.extend_from_slice(&self.contents);
  37. NetworkPacket(contents)
  38. }
  39. }
  40. /// reads a `Packet` from a stream
  41. pub async fn read<S>(stream: &mut S) -> Result<Option<Packet>>
  42. where
  43. S: AsyncReadExt + Unpin,
  44. {
  45. let mut info_buf = [0u8; 5];
  46. let check = stream.read(&mut info_buf).await?;
  47. if check == 0 {
  48. return Ok(None);
  49. }
  50. let packet_kind = PacketKind::from_u8(info_buf[0]).unwrap();
  51. let length = u32::from_le_bytes(info_buf[1..5].try_into().unwrap()) as usize;
  52. let mut contents: Vec<u8> = vec![0; length];
  53. stream.read(&mut contents).await?;
  54. let packet = Packet::new(packet_kind, contents);
  55. Ok(Some(packet))
  56. }
  57. /// Writes a `Sendable` packet to a stream
  58. pub async fn write<S, P>(stream: &mut S, packet: P) -> Result<()>
  59. where
  60. S: AsyncWriteExt + Unpin,
  61. P: Sendable,
  62. {
  63. let network_packet = packet.to_packet()?.to_network_packet();
  64. stream.write(&network_packet.0).await?;
  65. Ok(())
  66. }
  67. /// Kinds of packets that can be sent
  68. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  69. #[repr(u8)]
  70. pub enum PacketKind {
  71. Message = 0,
  72. PublicKey = 1,
  73. }
  74. impl PacketKind {
  75. /// returns `Option<PacketKind> given valid matching variant
  76. pub fn from_u8(kind: u8) -> Option<PacketKind> {
  77. match kind {
  78. 0 => Some(PacketKind::Message),
  79. _ => None,
  80. }
  81. }
  82. }