1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
use {ClientPacket, ServerPacket}; use std::error::Error; type ServerPacketIterator = Box<Iterator<Item = Vec<u8>>>; /// Interface to implement for all protocols. pub trait Protocol: Sync + Send { type SerializeError: Error; type DeserializeError: Error; /// Unique version number for the protocol. fn version(&self) -> u8; /// Serialize a client packet into some number of /// binary packet bodies. /// /// For most packets this should be a 1-to-1 deserialization /// but the iterator return type is there to allow for /// polyfilling of the packets behind the scenes if a /// protocol backend doesn't support them directly. /// This can be used (for example) to send multiple packets /// for when more than 255 missiles are reflected with /// the same goliath deflect (which is not supported by /// protocol-v5). /// /// For users of this interface it will most likely be /// more convienient to call /// [`ProtocolSerializationExt::serialize()`][2] with a /// [`ClientPacket`][1] instead, since it provides a /// unified interface to serializing a [`ClientPacket`][1] /// and a [`ServerPacket`][0]. /// /// # Panics /// This method should never panic (based on the input), /// instead it should return an appropriate error within /// the SerializeError type. /// /// [0]: struct.ServerPacket.html /// [1]: struct.ClientPacket.html /// [2]: trait.ProtocolSerializationExt.html#ty.serialize fn serialize_client( &self, packet: &ClientPacket, ) -> Result<ServerPacketIterator, Self::SerializeError>; /// Serialize a server packet into some number of /// binary packet bodies. /// /// For most packets this should be a 1-to-1 deserialization /// but the iterator return type is there to allow for /// polyfilling of the packets behind the scenes if a /// protocol backend doesn't support them directly. /// This can be used (for example) to send multiple packets /// for when more than 255 missiles are reflected with /// the same goliath deflect (which is not supported by /// protocol-v5). /// /// For users of this interface it will most likely be /// more convienient to call /// [`ProtocolSerializationExt::serialize()`][2] with a /// [`ServerPacket`][0] instead, since it provides a /// unified interface to serializing a [`ServerPacket`][0] /// and a [`ClientPacket`][1]. /// /// # Panics /// This method should never panic (based on the input), /// instead it should return an appropriate error within /// the SerializeError type. /// /// [0]: struct.ServerPacket.html /// [1]: struct.ClientPacket.html /// [2]: trait.ProtocolSerializationExt.html#ty.serialize fn serialize_server( &self, packet: &ServerPacket, ) -> Result<ServerPacketIterator, Self::SerializeError>; /// Deserialize a binary packet into a client packet. fn deserialize_client(&self, data: &[u8]) -> Result<ClientPacket, Self::DeserializeError>; /// Deserialize a binary packet into a server packet. fn deserialize_server(&self, data: &[u8]) -> Result<ServerPacket, Self::DeserializeError>; } /// Helper trait to make working with protocols easier. /// /// This allows for [`ServerPacket`][0] and /// [`ClientPacket`][1] to be serialized and deserialized /// without using the `serialize_*` or `deserialize_*` /// methods within the [`Protocol`] trait. Instead they /// can use [`serialize`][2] and [`deserialize`][3] and /// let type inference deduce the correct type. /// /// **This trait should not be implemented by client code.** /// /// [0]: enum.ServerPacket.html /// [1]: enum.ClientPacket.html /// [2]: #tymethod.serialize /// [3]: #tymethod.deserialize pub trait ProtocolSerializationExt<T>: Protocol { fn serialize<U>(&self, packet: U) -> Result<ServerPacketIterator, Self::SerializeError> where U: Into<T>; fn deserialize(&self, data: &[u8]) -> Result<T, Self::DeserializeError>; } impl<T> ProtocolSerializationExt<ServerPacket> for T where T: Protocol + Sync + Send, { fn serialize<U>(&self, packet: U) -> Result<ServerPacketIterator, Self::SerializeError> where U: Into<ServerPacket>, { self.serialize_server(&packet.into()) } fn deserialize(&self, data: &[u8]) -> Result<ServerPacket, Self::DeserializeError> { self.deserialize_server(data) } } impl<T> ProtocolSerializationExt<ClientPacket> for T where T: Protocol + Sync + Send, { fn serialize<U>(&self, packet: U) -> Result<ServerPacketIterator, Self::SerializeError> where U: Into<ClientPacket>, { self.serialize_client(&packet.into()) } fn deserialize(&self, data: &[u8]) -> Result<ClientPacket, Self::DeserializeError> { self.deserialize_client(data) } }