Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serde to BlockPos #172

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
49 changes: 47 additions & 2 deletions azalea-core/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
//! The most common ones are [`Vec3`] and [`BlockPos`], which are usually used
//! for entity positions and block positions, respectively.

use crate::resource_location::ResourceLocation;
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::{
fmt,
hash::Hash,
io::{Cursor, Write},
ops::{Add, AddAssign, Mul, Rem, Sub},
};

use crate::resource_location::ResourceLocation;
use std::num::{ParseFloatError, ParseIntError};

macro_rules! vec3_impl {
($name:ident, $type:ty) => {
Expand Down Expand Up @@ -211,6 +214,7 @@ macro_rules! vec3_impl {
/// Used to represent an exact position in the world where an entity could be.
/// For blocks, [`BlockPos`] is used instead.
#[derive(Clone, Copy, Debug, Default, PartialEq, McBuf)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Vec3 {
pub x: f64,
pub y: f64,
Expand All @@ -235,6 +239,7 @@ impl Vec3 {
/// The coordinates of a block in the world. For entities (if the coordinate
/// with decimals), use [`Vec3`] instead.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct BlockPos {
pub x: i32,
pub y: i32,
Expand Down Expand Up @@ -571,6 +576,46 @@ impl fmt::Display for Vec3 {
}
}

impl FromStr for BlockPos {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let pos = s
.split(' ')
.collect::<Vec<_>>();

if pos.len() != 3 {
return Err("Must be a length of 3".to_string());
}

Ok(BlockPos {
x: pos[0].parse().map_err(|e: ParseIntError| e.to_string())?,
y: pos[1].parse().map_err(|e: ParseIntError| e.to_string())?,
z: pos[2].parse().map_err(|e: ParseIntError| e.to_string())?,
})
}
}

impl FromStr for Vec3 {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let pos = s
.split(' ')
.collect::<Vec<_>>();

if pos.len() != 3 {
return Err("Must be a length of 3".to_string());
}

Ok(Vec3 {
x: pos[0].parse().map_err(|e: ParseFloatError| e.to_string())?,
y: pos[1].parse().map_err(|e: ParseFloatError| e.to_string())?,
z: pos[2].parse().map_err(|e: ParseFloatError| e.to_string())?,
})
}
}

const PACKED_X_LENGTH: u64 = 1 + 25; // minecraft does something a bit more complicated to get this 25
const PACKED_Z_LENGTH: u64 = PACKED_X_LENGTH;
const PACKED_Y_LENGTH: u64 = 64 - PACKED_X_LENGTH - PACKED_Z_LENGTH;
Expand Down
Loading