1
0
Lixcraft/src/datatypes.rs

134 Zeilen
3.5 KiB
Rust

2022-03-01 20:45:10 +01:00
use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Error;
use lixcraft_derive::Wrapper;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Wrapper)]
pub struct VarInt(pub i32);
impl From<VarInt> for usize {
fn from(v: VarInt) -> Self {
v.0 as usize
}
}
impl From<usize> for VarInt {
fn from(v: usize) -> Self {
VarInt(v as i32)
}
}
impl Serialize for VarInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let mut v = self.0 as u32;
loop {
if v & 0x80 == 0 {
return serializer.serialize_u8(v as u8);
}
serializer.serialize_u8((v as u8 & 0x7f) | 0x80)?;
v >>= 7;
}
}
}
impl<'de> Deserialize<'de> for VarInt {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
let mut num_read = 0;
let mut result = 0;
loop {
let read = u8::deserialize(deserializer)?;
let value = i32::from(read & 0b0111_1111);
result |= value.overflowing_shl(7 * num_read).0;
num_read += 1;
if num_read > 5 {
return Err(D::Error::custom("VarInt too large"));
}
if read & 0b1000_0000 == 0 {
break;
}
}
Ok(VarInt(result))
}
}
#[derive(Debug)]
pub enum NextState {
Status,
Login
}
impl Serialize for NextState {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
VarInt::from(match self {
NextState::Status => 1,
NextState::Login => 2
}).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for NextState {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
match VarInt::deserialize(deserializer)? {
VarInt(1) => Ok(NextState::Status),
VarInt(2) => Ok(NextState::Login),
_ => Err(D::Error::custom("Invalid NextState"))
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseVersion {
name: String,
protocol: i32
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseSample {
name: String,
id: String
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponsePlayers {
max: i32,
online: i32,
sample: Vec<StatusResponseSample>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseDescription {
text: String
}
#[derive(Debug)]
pub struct StatusResponse {
version: StatusResponseVersion,
players: StatusResponsePlayers,
description: StatusResponseDescription,
//#[serde(skip_serializing_if = "Option::is_none")]
favicon: Option<String>
}
impl Serialize for StatusResponse {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_str(&match serde_json::to_string(self) {
Ok(v) => v,
Err(_) => return Err(serde::ser::Error::custom("Could not serialize status response"))
})
}
}
impl<'de> Deserialize<'de> for StatusResponse {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
match String::deserialize(deserializer) {
Ok(json) => match serde_json::from_str(&json) {
Ok(v) => Ok(v),
Err(_) => Err(D::Error::custom("Could not parse json status response"))
},
Err(err) => Err(err)
}
}
}