Isabelle's Lazy Message Protocol
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 rivejä
2.5 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. ///
  42. /// if `Ok(None)` is returned the stream has been disconnected.
  43. pub async fn read<S>(stream: &mut S) -> Result<Option<Packet>>
  44. where
  45. S: AsyncReadExt + Unpin,
  46. {
  47. let mut info_buf = [0u8; 5];
  48. let check = stream.read(&mut info_buf).await?;
  49. if check == 0 {
  50. return Ok(None);
  51. }
  52. let packet_kind = PacketKind::from_u8(info_buf[0]).unwrap();
  53. let length = u32::from_le_bytes(info_buf[1..5].try_into().unwrap()) as usize;
  54. let mut contents: Vec<u8> = vec![0; length];
  55. stream.read(&mut contents).await?;
  56. let packet = Packet::new(packet_kind, contents);
  57. Ok(Some(packet))
  58. }
  59. /// Writes a `Sendable` packet to a stream
  60. pub async fn write<S, P>(stream: &mut S, packet: P) -> Result<()>
  61. where
  62. S: AsyncWriteExt + Unpin,
  63. P: Sendable,
  64. {
  65. let network_packet = packet.to_packet()?.to_network_packet();
  66. stream.write(&network_packet.0).await?;
  67. Ok(())
  68. }
  69. /// Kinds of packets that can be sent
  70. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  71. #[repr(u8)]
  72. pub enum PacketKind {
  73. Message = 0,
  74. PublicKey = 1,
  75. }
  76. impl PacketKind {
  77. /// returns `Option<PacketKind> given valid matching variant
  78. pub fn from_u8(kind: u8) -> Option<PacketKind> {
  79. match kind {
  80. 0 => Some(PacketKind::Message),
  81. _ => None,
  82. }
  83. }
  84. }