Add field data type modification

This commit is contained in:
Vladislavs Golubs 2021-02-07 16:46:00 +03:00
parent 99a331c6ab
commit 87b1e7a250
4 changed files with 38 additions and 17 deletions

View File

@ -3,6 +3,7 @@ use std::collections::HashSet;
use std::fmt; use std::fmt;
use std::fmt::Display; use std::fmt::Display;
#[derive(Debug)]
pub enum State { pub enum State {
Handshake, Handshake,
Status, Status,
@ -13,10 +14,10 @@ pub enum State {
impl State { impl State {
pub fn data_import(&self) -> &str { pub fn data_import(&self) -> &str {
match self { match self {
State::Handshake => "crate::packet::handshake", State::Handshake => "crate::data::handshake::*",
State::Status => "crate::packet::status", State::Status => "crate::data::status::*",
State::Login => "crate::packet::login", State::Login => "crate::data::login::*",
State::Game => "crate::packet::game", State::Game => "crate::data::game::*",
} }
} }
} }
@ -50,7 +51,7 @@ impl Display for Bound {
} }
} }
#[derive(Serialize)] #[derive(Serialize, Debug)]
pub struct Packet { pub struct Packet {
pub id: u8, pub id: u8,
pub name: String, pub name: String,
@ -67,7 +68,7 @@ impl Packet {
} }
} }
#[derive(Serialize)] #[derive(Serialize, Debug)]
pub struct Field { pub struct Field {
pub name: String, pub name: String,
#[serde(flatten)] #[serde(flatten)]
@ -81,9 +82,13 @@ impl Field {
data_type, data_type,
} }
} }
pub fn change_type(&self, data_type: DataType) -> Field {
Field::new(&self.name, data_type)
}
} }
#[derive(Serialize, Eq, PartialEq)] #[derive(Serialize, Eq, PartialEq, Debug)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum DataType { pub enum DataType {
#[serde(rename(serialize = "bool"))] #[serde(rename(serialize = "bool"))]
@ -137,6 +142,7 @@ impl DataType {
} }
} }
#[derive(Debug)]
pub struct Protocol { pub struct Protocol {
pub state: State, pub state: State,
pub server_bound_packets: Vec<Packet>, pub server_bound_packets: Vec<Packet>,

View File

@ -6,6 +6,7 @@ use heck::{CamelCase, SnakeCase};
use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::input::{Container, Data, ProtocolData, ProtocolState};
use crate::data::output; use crate::data::output;
use crate::data::output::Field;
use serde::Serialize; use serde::Serialize;
use serde_json::json; use serde_json::json;
use std::collections::HashMap; use std::collections::HashMap;
@ -132,7 +133,7 @@ fn transform_protocol_data(
let id = *packet_ids let id = *packet_ids
.get(no_prefix_name) .get(no_prefix_name)
.expect("Failed to get packet id"); .expect("Failed to get packet id");
let name = rename_packet(&no_prefix_name.to_camel_case(), &bound); let packet_name = rename_packet(&no_prefix_name.to_camel_case(), &bound);
let mut fields = vec![]; let mut fields = vec![];
@ -142,14 +143,14 @@ fn transform_protocol_data(
match container { match container {
Container::Value { name, data } => { Container::Value { name, data } => {
if let Some(field) = transform_field(name, data) { if let Some(field) = transform_field(name, data) {
fields.push(field); fields.push(modify_field(&packet_name, field));
} }
} }
Container::List { name, data_vec } => { Container::List { name, data_vec } => {
if let Some(name) = name { if let Some(name) = name {
for data in data_vec { for data in data_vec {
if let Some(field) = transform_field(name, data) { if let Some(field) = transform_field(name, data) {
fields.push(field); fields.push(modify_field(&packet_name, field));
} }
} }
} }
@ -159,7 +160,11 @@ fn transform_protocol_data(
} }
} }
let packet = output::Packet { id, name, fields }; let packet = output::Packet {
id,
name: packet_name,
fields,
};
packets.push(packet); packets.push(packet);
} }
@ -218,8 +223,8 @@ fn format_field_name(unformatted_field_name: &str) -> String {
} }
} }
fn transform_data_type(str_type: &str) -> Option<output::DataType> { fn transform_data_type(name: &str) -> Option<output::DataType> {
match str_type { match name {
"bool" => Some(output::DataType::Boolean), "bool" => Some(output::DataType::Boolean),
"i8" => Some(output::DataType::Byte), "i8" => Some(output::DataType::Byte),
"i16" => Some(output::DataType::Short), "i16" => Some(output::DataType::Short),
@ -237,12 +242,21 @@ fn transform_data_type(str_type: &str) -> Option<output::DataType> {
"buffer" => Some(output::DataType::ByteArray { rest: false }), "buffer" => Some(output::DataType::ByteArray { rest: false }),
"restBuffer" => Some(output::DataType::ByteArray { rest: true }), "restBuffer" => Some(output::DataType::ByteArray { rest: true }),
_ => { _ => {
println!("{}", str_type); println!("Unknown data type \"{}\"", name);
None None
} }
} }
} }
fn modify_field(packet_name: &str, field: output::Field) -> output::Field {
match (packet_name, field.name.as_str()) {
("StatusResponse", "response") => field.change_type(output::DataType::RefType {
ref_name: "ServerStatus".to_owned(),
}),
_ => field,
}
}
fn rename_packet(name: &str, bound: &output::Bound) -> String { fn rename_packet(name: &str, bound: &output::Bound) -> String {
match (name, bound) { match (name, bound) {
("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse",

View File

@ -32,7 +32,7 @@ impl {{packet_enum_name}} {
} }
} }
{{#each packets as |p|}} {{#each packets as |p|}}
pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{f.type}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{#if (ne f.type "RefType")}}{{f.type}}{{~else}}{{f.ref_name}}{{/if}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self {
{{~#if p.fields}} {{~#if p.fields}}
let {{snake_case p.name}} = {{p.name}} { let {{snake_case p.name}} = {{p.name}} {
{{~#each p.fields as |f|}} {{~#each p.fields as |f|}}

View File

@ -1,5 +1,6 @@
// This file is automatically generated. // This file is automatically generated.
// It is not intended for manual editing. // It is not intended for manual editing.
use crate::data::status::*;
use crate::DecodeError; use crate::DecodeError;
use crate::Decoder; use crate::Decoder;
use minecraft_protocol_derive::Packet; use minecraft_protocol_derive::Packet;
@ -70,7 +71,7 @@ impl StatusClientBoundPacket {
} }
} }
pub fn status_response(response: String) -> Self { pub fn status_response(response: ServerStatus) -> Self {
let status_response = StatusResponse { response }; let status_response = StatusResponse { response };
Self::StatusResponse(status_response) Self::StatusResponse(status_response)
@ -90,7 +91,7 @@ pub struct PingRequest {
#[derive(Packet, Debug)] #[derive(Packet, Debug)]
pub struct StatusResponse { pub struct StatusResponse {
pub response: String, pub response: ServerStatus,
} }
#[derive(Packet, Debug)] #[derive(Packet, Debug)]