From 4deb1954d5f565feb7dbbc007124455da085cf7f Mon Sep 17 00:00:00 2001 From: Joey Sacchini Date: Mon, 19 Oct 2020 12:22:05 -0400 Subject: fix mistakes when implementing no_std --- Cargo.lock | 7 +++++++ Cargo.toml | 3 +++ src/chat.rs | 4 ++-- src/deserialize.rs | 1 + src/lib.rs | 7 ++++--- src/nbt.rs | 4 ++-- src/protocol.rs | 40 +++++++++++++++++++++++++++++++--------- src/serialize.rs | 3 ++- src/status.rs | 5 +++-- src/types.rs | 9 +++++---- src/uuid.rs | 13 +++++++++++-- src/v1_15_2.rs | 6 +++--- 12 files changed, 74 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b731db..720eea9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,6 +74,7 @@ version = "0.2.0" dependencies = [ "base64", "flate2", + "no-std-compat", "paste", "rand", "serde", @@ -90,6 +91,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "paste" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 85dc86a..9de278b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ version = "1.0.116" features = [ "derive", "alloc" ] default-features = false +[target.'cfg(not(feature = "std"))'.dependencies] +no-std-compat = "0.4.1" + [dev-dependencies] flate2 = "1.0.17" diff --git a/src/chat.rs b/src/chat.rs index 3913a6c..d00e9f1 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1,4 +1,4 @@ -use alloc::{vec::Vec, string::{String, ToString}, fmt, collections::{BTreeMap}, boxed::Box, borrow::ToOwned}; +use alloc::{vec::Vec, string::{String, ToString}, collections::{BTreeMap}, boxed::Box, borrow::ToOwned, fmt, format}; use serde::{Serialize, Deserialize, Deserializer, de, Serializer}; use serde::de::{Visitor, Error, IntoDeserializer, MapAccess}; use serde::ser::SerializeMap; @@ -1040,7 +1040,7 @@ impl TestRandom for Chat { } } -#[cfg(all(test, feature = "std"))] +#[cfg(test)] pub mod tests { use super::*; diff --git a/src/deserialize.rs b/src/deserialize.rs index 0fd32a6..be5496e 100644 --- a/src/deserialize.rs +++ b/src/deserialize.rs @@ -53,6 +53,7 @@ impl fmt::Debug for DeserializeErr { } } +#[cfg(feature = "std")] impl std::error::Error for DeserializeErr {} impl<'b, R> Into> for DeserializeErr { diff --git a/src/lib.rs b/src/lib.rs index 3082bdf..4be590a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ #![feature(const_fn)] #![feature(test)] -#![cfg_attr(not(test), no_std)] +#![cfg_attr(all(not(test), not(feature="std")), no_std)] extern crate alloc; @@ -17,9 +17,10 @@ pub mod utils; pub mod uuid; pub mod v1_15_2; +mod chat; + pub use deserialize::*; pub use serialize::*; #[cfg(all(test, feature = "std"))] -mod test_macros; -mod chat; +mod test_macros; \ No newline at end of file diff --git a/src/nbt.rs b/src/nbt.rs index 3424b9a..ae4aae5 100644 --- a/src/nbt.rs +++ b/src/nbt.rs @@ -2,7 +2,7 @@ use crate::utils::{ read_int, read_long, read_one_byte, read_short, take, write_int, write_long, write_short, }; use crate::{DeserializeErr, DeserializeResult, Deserialized}; -use alloc::{string::{String, ToString}, borrow::ToOwned, fmt, vec::Vec}; +use alloc::{string::{String, ToString}, borrow::ToOwned, fmt, vec::Vec, vec, format}; #[cfg(all(test, feature = "std"))] use crate::protocol::TestRandom; @@ -518,7 +518,7 @@ impl Tag { } // test -#[cfg(all(test, feature = "std"))] +#[cfg(test)] mod tests { use super::*; use flate2::read::GzDecoder; diff --git a/src/protocol.rs b/src/protocol.rs index 9e7307e..2e0151d 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -61,6 +61,7 @@ impl fmt::Debug for PacketErr { } } +#[cfg(feature = "std")] impl std::error::Error for PacketErr {} #[derive(Debug, Clone, PartialEq)] @@ -243,14 +244,14 @@ macro_rules! define_protocol { pub fn describe() -> crate::protocol::ProtocolSpec { crate::protocol::ProtocolSpec { name: stringify!($packett).to_owned(), - packets: vec!( + packets: alloc::vec!( $(crate::protocol::ProtocolPacketSpec{ state: stringify!($state).to_owned(), direction: stringify!($direction).to_owned(), id: $id, name: stringify!($nam).to_owned(), body_struct: stringify!($body).to_owned(), - fields: vec!( + fields: alloc::vec!( $(crate::protocol::ProtocolPacketField{ name: stringify!($fnam).to_owned(), kind: stringify!($ftyp).to_owned(), @@ -262,6 +263,7 @@ macro_rules! define_protocol { } } + #[cfg(feature = "std")] impl<'a> std::convert::TryFrom> for $rawpackett<'a> { type Error = crate::protocol::PacketErr; @@ -270,19 +272,30 @@ macro_rules! define_protocol { use self::$statet::*; use self::$directiont::*; use crate::protocol::PacketErr::*; + #[cfg(feature = "std")] + use std::marker; + #[cfg(not(feature = "std"))] + use no_std_compat::marker; match (value.id.id, value.id.state, value.id.direction) { $(($id, $state, $direction) => Ok($nam($rawdt { data: value.data, - _typ: std::marker::PhantomData, + _typ: marker::PhantomData, }))),*, other => Err(UnknownId(other.0)) } } } + #[cfg(feature = "std")] impl<'a> std::convert::Into> for $rawpackett<'a> { fn into(self) -> crate::protocol::RawPacket<'a, $idi> { + self.into_raw_packet() + } + } + + impl<'a> $rawpackett<'a> { + fn into_raw_packet(self) -> crate::protocol::RawPacket<'a, $idi> { crate::protocol::RawPacket { id: self.id(), data: self.bytes(), @@ -290,6 +303,7 @@ macro_rules! define_protocol { } } + #[cfg(feature = "std")] impl<'a> std::convert::Into<&'a [u8]> for $rawpackett<'a> { fn into(self) -> &'a [u8] { use self::$rawpackett::*; @@ -313,7 +327,7 @@ macro_rules! define_protocol { pub fn deserialize(self) -> Result<$packett, crate::protocol::PacketErr> { use crate::protocol::Packet; - $packett::mc_deserialize(self.into()) + $packett::mc_deserialize(self.into_raw_packet()) } pub fn bytes(&self) -> &'a [u8] { @@ -325,12 +339,20 @@ macro_rules! define_protocol { } } + #[cfg(feature = "std")] #[derive(PartialEq, Debug)] pub struct $rawdt<'a, T> { pub data: &'a [u8], _typ: std::marker::PhantomData } + #[cfg(not(feature = "std"))] + #[derive(PartialEq, Debug)] + pub struct $rawdt<'a, T> { + pub data: &'a [u8], + _typ: no_std_compat::marker::PhantomData + } + impl<'a, T> $rawdt<'a, T> where T: crate::Deserialize { pub fn deserialize(&self) -> Result { use crate::protocol::PacketErr::*; @@ -405,7 +427,7 @@ macro_rules! proto_enum_with_type { match id.into() { $($bval => proto_enum_deserialize_variant!(data, $typname::$nam $(($bod))?)),*, other => { - return Err(DeserializeErr::CannotUnderstandValue(format!("invalid {} {:?}", stringify!($typname), other))) + return Err(DeserializeErr::CannotUnderstandValue(alloc::format!("invalid {} {:?}", stringify!($typname), other))) } } } @@ -510,7 +532,7 @@ macro_rules! proto_str_enum { pub fn deserialize_with_id<'a>(name: &str, data: &'a[u8]) -> DeserializeResult<'a, Self> { match name { $($sval => proto_enum_deserialize_variant!(data, $typname::$nam $(($bod))?)),*, - other => Err(DeserializeErr::CannotUnderstandValue(format!("invalid {} ident '{}'", stringify!($typname), other))) + other => Err(DeserializeErr::CannotUnderstandValue(alloc::format!("invalid {} ident '{}'", stringify!($typname), other))) } } @@ -689,7 +711,7 @@ macro_rules! counted_array_type { T: Debug + Clone + PartialEq, { type Item = &'a mut T; - type IntoIter = std::slice::IterMut<'a, T>; + type IntoIter = alloc::slice::IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter { let data = &mut self.data; @@ -702,7 +724,7 @@ macro_rules! counted_array_type { T: Debug + Clone + PartialEq, { type Item = &'a T; - type IntoIter = std::slice::Iter<'a, T>; + type IntoIter = alloc::slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { let data = &self.data; @@ -715,7 +737,7 @@ macro_rules! counted_array_type { T: Debug + Clone + PartialEq, { type Item = T; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.data.into_iter() diff --git a/src/serialize.rs b/src/serialize.rs index 3b96a3f..c23ea09 100644 --- a/src/serialize.rs +++ b/src/serialize.rs @@ -1,4 +1,4 @@ -use alloc::{string::String, fmt}; +use alloc::{string::String, fmt, vec}; pub enum SerializeErr { FailedJsonEncode(String), @@ -21,6 +21,7 @@ impl fmt::Debug for SerializeErr { } } +#[cfg(feature = "std")] impl std::error::Error for SerializeErr {} pub type SerializeResult = Result<(), SerializeErr>; diff --git a/src/status.rs b/src/status.rs index 6944e89..08e3e71 100644 --- a/src/status.rs +++ b/src/status.rs @@ -5,7 +5,8 @@ use crate::{ SerializeErr, SerializeResult, }; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use alloc::{string::String, fmt, vec::Vec}; +use alloc::{string::String, fmt, vec::Vec, borrow::ToOwned}; +use alloc::format; #[cfg(all(test, feature = "std"))] use crate::protocol::TestRandom; @@ -94,7 +95,7 @@ impl Serialize for StatusFaviconSpec { S: Serializer, { let data_base64 = base64::encode(self.data.as_slice()); - let content = format!("data:{};base64,{}", self.content_type, data_base64); + let content = alloc::format!("data:{};base64,{}", self.content_type, data_base64); serializer.serialize_str(content.as_str()) } } diff --git a/src/types.rs b/src/types.rs index 47df47b..f22b280 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ // ... PRIMITIVE TYPES ... -use alloc::{string::String, vec::Vec}; +use alloc::{string::String, vec::Vec, fmt}; use crate::utils::*; use crate::uuid::UUID4; use crate::*; @@ -251,8 +251,8 @@ impl From for VarInt { } } -impl std::fmt::Display for VarInt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Display for VarInt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "VarInt({})", self.0) } } @@ -739,7 +739,7 @@ impl TestRandom for Slot { } } -#[cfg(all(test, feature = "std"))] +#[cfg(test)] mod tests { use super::*; use alloc::fmt::Debug; @@ -905,6 +905,7 @@ mod tests { }); } + #[cfg(feature = "std")] #[test] fn test_uuid() { for _ in 0..5 { diff --git a/src/uuid.rs b/src/uuid.rs index 0b9d8ba..9fcdacd 100644 --- a/src/uuid.rs +++ b/src/uuid.rs @@ -46,7 +46,7 @@ impl<'de> serde::Deserialize<'de> for UUID4 { impl serde::de::Visitor<'_> for Visitor { type Value = UUID4; - fn expecting(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { + fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { write!(formatter, "a string representing the UUID") } @@ -185,11 +185,13 @@ fn str_split(source: &str, n: usize) -> Option<(&str, &str)> { } } -#[cfg(all(test, feature = "std"))] +#[cfg(test)] mod tests { use super::UUID4; + #[cfg(feature = "std")] use alloc::string::ToString; + #[cfg(feature = "std")] #[test] fn test_random_uuid4() { UUID4::random(); @@ -218,6 +220,7 @@ mod tests { assert_eq!(uuid_a, uuid_b); } + #[cfg(feature = "std")] #[test] fn test_random_uuid4_hex() { let src_uuid = UUID4::random(); @@ -229,16 +232,19 @@ mod tests { assert_eq!(uuid_hex, uuid_parsed_hex); } + #[cfg(feature = "std")] #[test] fn test_display_uuid() { println!("got uuid {}", UUID4::random()); } + #[cfg(feature = "std")] #[test] fn test_debug_uuid() { println!("got uuid {:?}", UUID4::random()); } + #[cfg(feature = "std")] #[test] fn test_to_json() { let id = UUID4::random(); @@ -246,6 +252,7 @@ mod tests { assert_eq!(str, format!("\"{}\"", id.to_string())) } + #[cfg(feature = "std")] #[test] fn test_from_json() { let id = UUID4::random(); @@ -254,6 +261,7 @@ mod tests { assert_eq!(deserialized, id); } + #[cfg(feature = "std")] #[bench] fn bench_parse_uuid4(b: &mut test::Bencher) { let rand = UUID4::random(); @@ -264,6 +272,7 @@ mod tests { }) } + #[cfg(feature = "std")] #[bench] fn bench_uuid4_to_str(b: &mut test::Bencher) { let rand = UUID4::random(); diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs index 77d01f9..245d20e 100644 --- a/src/v1_15_2.rs +++ b/src/v1_15_2.rs @@ -1843,7 +1843,7 @@ impl Deserialize for GameChangeReason { 0x09 => Deserialized::ok(PufferfishSting, data), 0x0A => Deserialized::ok(ElderGuardianMobAppearance, data), 0x0B => Ok(RespawnRequestType::deserialize_with_id(value as u8, data)?.map(move |mode| Respawn(mode))), - other => Err(DeserializeErr::CannotUnderstandValue(format!( + other => Err(DeserializeErr::CannotUnderstandValue(alloc::format!( "invalid game change reason id {}", other ))), @@ -2800,7 +2800,7 @@ impl LightingData { if update_mask.0 & (1 << i) != 0 { let Deserialized { value: length, data: rest } = VarInt::mc_deserialize(data)?; if (length.0 as usize) != LIGHT_DATA_LENGTH { - return Err(DeserializeErr::CannotUnderstandValue(format!("bad data length in light update {}", length))); + return Err(DeserializeErr::CannotUnderstandValue(alloc::format!("bad data length in light update {}", length))); } data = rest; @@ -3419,7 +3419,7 @@ pub mod tests { fn test_generate_test_cases() { Packet578::describe().packets.iter().map(move |packet| { let snake_case = to_snake_case(packet.name.clone()); - format!("packet_test_cases!(Packet578, {}, {},\n test_{}, bench_write_{}, bench_read_{});\n", + alloc::format!("packet_test_cases!(Packet578, {}, {},\n test_{}, bench_write_{}, bench_read_{});\n", packet.name, packet.body_struct, snake_case, snake_case, snake_case).to_owned() }).for_each(move |line| { println!("{}", line) -- cgit