mirror of
https://github.com/lcdr/lu_packets.git
synced 2026-02-07 10:42:04 -06:00
Use a derive macro to generate message sending cast implementations
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
target/*
|
||||
lu_packets_derive/target*
|
||||
|
||||
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -23,6 +23,16 @@ name = "lu_packets"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"endio 0.2.0 (git+https://github.com/lcdr/endio?rev=cb5020f6749a301ae925592f9ad1920919894ddb)",
|
||||
"lu_packets_derive 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lu_packets_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -8,3 +8,4 @@ repository = "https://github.com/lcdr/lu_packets/"
|
||||
|
||||
[dependencies]
|
||||
endio = { git = "https://github.com/lcdr/endio", rev = "cb5020f6749a301ae925592f9ad1920919894ddb" }
|
||||
lu_packets_derive = { path = "lu_packets_derive" }
|
||||
|
||||
45
lu_packets_derive/Cargo.lock
generated
Normal file
45
lu_packets_derive/Cargo.lock
generated
Normal file
@@ -0,0 +1,45 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "lu_packets_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
15
lu_packets_derive/Cargo.toml
Normal file
15
lu_packets_derive/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "lu_packets_derive"
|
||||
version = "0.1.0"
|
||||
authors = ["lcdr"]
|
||||
edition = "2018"
|
||||
license = "AGPL-3.0-or-later"
|
||||
repository = "https://github.com/lcdr/lu_packets/"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = "1.0"
|
||||
42
lu_packets_derive/src/lib.rs
Normal file
42
lu_packets_derive/src/lib.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, Data, DeriveInput, Fields};
|
||||
|
||||
#[proc_macro_derive(FromVariants)]
|
||||
pub fn derive_deserialize(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
let data = match &input.data {
|
||||
Data::Enum(data) => data,
|
||||
_ => panic!("only enums are supported"),
|
||||
};
|
||||
|
||||
let name = &input.ident;
|
||||
|
||||
let mut impls = vec![];
|
||||
for v in &data.variants {
|
||||
let variant = &v.ident;
|
||||
let fields = match &v.fields {
|
||||
Fields::Named(_) => panic!("use a tuple or unit variant"),
|
||||
Fields::Unit => { continue }
|
||||
Fields::Unnamed(fields) => fields,
|
||||
};
|
||||
|
||||
if fields.unnamed.len() != 1 {
|
||||
panic!("use exactly one tuple argument");
|
||||
}
|
||||
let first = fields.unnamed.first().unwrap();
|
||||
let variant_ty = &first.ty;
|
||||
|
||||
let impl_ = quote! {
|
||||
impl ::std::convert::From<#variant_ty> for Message {
|
||||
fn from(msg: #variant_ty) -> Self {
|
||||
#name::#variant(msg).into()
|
||||
}
|
||||
}
|
||||
};
|
||||
impls.push(impl_);
|
||||
}
|
||||
(quote! {
|
||||
#(#impls)*
|
||||
}).into()
|
||||
}
|
||||
@@ -2,50 +2,26 @@ use std::io::Result as Res;
|
||||
|
||||
use endio::{LEWrite, Serialize};
|
||||
use endio::LittleEndian as LE;
|
||||
use lu_packets_derive::FromVariants;
|
||||
|
||||
use crate::common::{LuStr33, LuWStr33, ServiceId};
|
||||
use crate::general::client::{GeneralMessage, Handshake};
|
||||
use crate::common::{LuStr33, LuWStr33};
|
||||
|
||||
pub type LuMessage = crate::general::client::LuMessage<ClientMessage>;
|
||||
pub type Message = crate::raknet::client::Message<LuMessage>;
|
||||
|
||||
impl From<GeneralMessage> for Message {
|
||||
fn from(msg: GeneralMessage) -> Self {
|
||||
LuMessage::General(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Handshake> for Message {
|
||||
fn from(msg: Handshake) -> Self {
|
||||
GeneralMessage::Handshake(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[repr(u16)]
|
||||
pub enum LuMessage {
|
||||
General(GeneralMessage) = ServiceId::General as u16,
|
||||
Client(ClientMessage) = ServiceId::Client as u16,
|
||||
}
|
||||
|
||||
impl From<LuMessage> for Message {
|
||||
fn from(msg: LuMessage) -> Self {
|
||||
Message::UserMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum ClientMessage {
|
||||
LoginResponse(LoginResponse),
|
||||
}
|
||||
|
||||
impl From<ClientMessage> for Message {
|
||||
fn from(msg: ClientMessage) -> Self {
|
||||
LuMessage::Client(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromVariants)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum ClientMessage {
|
||||
LoginResponse(LoginResponse),
|
||||
}
|
||||
|
||||
impl<'a, W: LEWrite> Serialize<LE, W> for &'a ClientMessage
|
||||
where u8: Serialize<LE, W>,
|
||||
u32: Serialize<LE, W>,
|
||||
@@ -75,12 +51,6 @@ pub enum LoginResponse {
|
||||
InvalidUsernamePassword = 6,
|
||||
}
|
||||
|
||||
impl From<LoginResponse> for Message {
|
||||
fn from(msg: LoginResponse) -> Self {
|
||||
ClientMessage::LoginResponse(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: LEWrite> Serialize<LE, W> for &'a LoginResponse
|
||||
where u8: Serialize<LE, W>,
|
||||
u16: Serialize<LE, W>,
|
||||
|
||||
@@ -5,6 +5,27 @@ use endio::LittleEndian as LE;
|
||||
|
||||
use crate::common::ServiceId;
|
||||
|
||||
pub type Message<C> = crate::raknet::client::Message<LuMessage<C>>;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[repr(u16)]
|
||||
pub enum LuMessage<C> {
|
||||
General(GeneralMessage) = ServiceId::General as u16,
|
||||
Client(C) = ServiceId::Client as u16,
|
||||
}
|
||||
|
||||
impl<C> From<LuMessage<C>> for Message<C> {
|
||||
fn from(msg: LuMessage<C>) -> Self {
|
||||
Message::UserMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> From<GeneralMessage> for Message<C> {
|
||||
fn from(msg: GeneralMessage) -> Self {
|
||||
LuMessage::General(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
@@ -13,6 +34,18 @@ pub enum GeneralMessage {
|
||||
DisconnectNotify(DisconnectNotify),
|
||||
}
|
||||
|
||||
impl<C> From<Handshake> for Message<C> {
|
||||
fn from(msg: Handshake) -> Self {
|
||||
GeneralMessage::Handshake(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> From<DisconnectNotify> for Message<C> {
|
||||
fn from(msg: DisconnectNotify) -> Self {
|
||||
GeneralMessage::DisconnectNotify(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: LEWrite> Serialize<LE, W> for &'a GeneralMessage
|
||||
where u8: Serialize<LE, W>,
|
||||
u32: Serialize<LE, W>,
|
||||
|
||||
@@ -2,44 +2,20 @@ use std::io::Result as Res;
|
||||
|
||||
use endio::{LEWrite, Serialize};
|
||||
use endio::LittleEndian as LE;
|
||||
use lu_packets_derive::FromVariants;
|
||||
|
||||
use crate::common::{ObjId, LuWStr33, ServiceId, ZoneId};
|
||||
use crate::general::client::{DisconnectNotify, GeneralMessage, Handshake};
|
||||
use crate::common::{ObjId, LuWStr33, ZoneId};
|
||||
|
||||
pub type LuMessage = crate::general::client::LuMessage<ClientMessage>;
|
||||
pub type Message = crate::raknet::client::Message<LuMessage>;
|
||||
|
||||
impl From<GeneralMessage> for Message {
|
||||
fn from(msg: GeneralMessage) -> Self {
|
||||
LuMessage::General(msg).into()
|
||||
impl From<ClientMessage> for Message {
|
||||
fn from(msg: ClientMessage) -> Self {
|
||||
LuMessage::Client(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Handshake> for Message {
|
||||
fn from(msg: Handshake) -> Self {
|
||||
GeneralMessage::Handshake(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DisconnectNotify> for Message {
|
||||
fn from(msg: DisconnectNotify) -> Self {
|
||||
GeneralMessage::DisconnectNotify(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[repr(u16)]
|
||||
pub enum LuMessage {
|
||||
General(GeneralMessage) = ServiceId::General as u16,
|
||||
Client(ClientMessage) = ServiceId::Client as u16,
|
||||
}
|
||||
|
||||
impl From<LuMessage> for Message {
|
||||
fn from(msg: LuMessage) -> Self {
|
||||
Message::UserMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, FromVariants)]
|
||||
#[non_exhaustive]
|
||||
#[repr(u32)]
|
||||
pub enum ClientMessage {
|
||||
@@ -48,12 +24,6 @@ pub enum ClientMessage {
|
||||
CharacterDeleteResponse(CharacterDeleteResponse) = 11,
|
||||
}
|
||||
|
||||
impl From<ClientMessage> for Message {
|
||||
fn from(msg: ClientMessage) -> Self {
|
||||
LuMessage::Client(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: LEWrite> Serialize<LE, W> for &'a ClientMessage
|
||||
where u8: Serialize<LE, W>,
|
||||
u32: Serialize<LE, W>,
|
||||
@@ -85,12 +55,6 @@ pub struct CharacterListResponse {
|
||||
pub chars: Vec<CharListChar>,
|
||||
}
|
||||
|
||||
impl From<CharacterListResponse> for Message {
|
||||
fn from(msg: CharacterListResponse) -> Self {
|
||||
ClientMessage::CharacterListResponse(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: LEWrite> Serialize<LE, W> for &'a CharacterListResponse
|
||||
where u8: Serialize<LE, W>,
|
||||
&'a CharListChar: Serialize<LE, W> {
|
||||
@@ -170,19 +134,7 @@ pub enum CharacterCreateResponse {
|
||||
CustomNameInUse,
|
||||
}
|
||||
|
||||
impl From<CharacterCreateResponse> for Message {
|
||||
fn from(msg: CharacterCreateResponse) -> Self {
|
||||
ClientMessage::CharacterCreateResponse(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct CharacterDeleteResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
impl From<CharacterDeleteResponse> for Message {
|
||||
fn from(msg: CharacterDeleteResponse) -> Self {
|
||||
ClientMessage::CharacterDeleteResponse(msg).into()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user