mindustry logic execution, map- and schematic- parsing and rendering
run clippy
bendn 2023-06-23
parent 4678316 · commit 58da0a1
-rw-r--r--src/access.rs16
-rw-r--r--src/block/base.rs37
-rw-r--r--src/block/defense.rs29
-rw-r--r--src/block/fluid.rs33
-rw-r--r--src/block/logic.rs121
-rw-r--r--src/block/mod.rs39
-rw-r--r--src/block/payload.rs60
-rw-r--r--src/block/power.rs37
-rw-r--r--src/block/simple.rs37
-rw-r--r--src/block/transport.rs86
-rw-r--r--src/data/base64.rs22
-rw-r--r--src/data/dynamic.rs46
-rw-r--r--src/data/mod.rs39
-rw-r--r--src/data/schematic.rs91
-rw-r--r--src/exe/args.rs88
-rw-r--r--src/exe/edit.rs12
-rw-r--r--src/exe/print.rs2
-rw-r--r--src/item/storage.rs44
-rw-r--r--src/logic/mod.rs4
-rw-r--r--src/registry.rs12
-rw-r--r--src/team.rs12
-rw-r--r--src/utils/once_cell.rs11
22 files changed, 321 insertions, 557 deletions
diff --git a/src/access.rs b/src/access.rs
index 8498741..44d421b 100644
--- a/src/access.rs
+++ b/src/access.rs
@@ -15,17 +15,11 @@ pub enum Access<'a, T: AsRef<B>, B: ?Sized> {
impl<'a, T: AsRef<B>, B> Access<'a, T, B> {
pub const fn is_borrowed(&self) -> bool {
- match self {
- Self::Borrowed(..) => true,
- _ => false,
- }
+ matches!(self, Self::Borrowed(..))
}
pub const fn is_owned(&self) -> bool {
- match self {
- Self::Owned(..) => true,
- _ => false,
- }
+ matches!(self, Self::Owned(..))
}
}
@@ -44,7 +38,7 @@ impl<'a, T: AsRef<B>, B: ?Sized> AsRef<B> for Access<'a, T, B> {
impl<'a, T: AsRef<B>, B: ?Sized> Borrow<B> for Access<'a, T, B> {
fn borrow(&self) -> &B {
match self {
- Self::Borrowed(r) => *r,
+ Self::Borrowed(r) => r,
Self::Owned(v) => v.as_ref(),
}
}
@@ -61,7 +55,7 @@ impl<'a, T: AsRef<B>, B: ?Sized> Deref for Access<'a, T, B> {
fn deref(&self) -> &Self::Target {
match self {
- Self::Borrowed(r) => *r,
+ Self::Borrowed(r) => r,
Self::Owned(v) => v.as_ref(),
}
}
@@ -77,7 +71,7 @@ impl<'a, T: AsRef<B>, B: ?Sized + Eq> Eq for Access<'a, T, B> {}
impl<'a, T: AsRef<B>, B: ?Sized + Hash> Hash for Access<'a, T, B> {
fn hash<H: Hasher>(&self, state: &mut H) {
- B::hash(self, state)
+ B::hash(self, state);
}
}
diff --git a/src/block/base.rs b/src/block/base.rs
index da1cdef..ded5ec4 100644
--- a/src/block/base.rs
+++ b/src/block/base.rs
@@ -2,7 +2,9 @@ use std::any::Any;
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
use crate::block::transport::ItemBlock;
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
use crate::item::storage::Storage;
@@ -40,10 +42,10 @@ impl From<u32> for RGBA {
impl From<RGBA> for u32 {
fn from(value: RGBA) -> Self {
- ((value.0 as u32) << 24)
- | ((value.1 as u32) << 16)
- | ((value.2 as u32) << 8)
- | (value.3 as u32)
+ (u32::from(value.0) << 24)
+ | (u32::from(value.1) << 16)
+ | (u32::from(value.2) << 8)
+ | u32::from(value.3)
}
}
@@ -54,10 +56,9 @@ pub struct LampBlock {
}
impl LampBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -69,25 +70,7 @@ impl LampBlock {
}
impl BlockLogic for LampBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Int(config))
diff --git a/src/block/defense.rs b/src/block/defense.rs
index 2f7eb46..05f8e98 100644
--- a/src/block/defense.rs
+++ b/src/block/defense.rs
@@ -1,7 +1,9 @@
use std::any::Any;
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
use crate::item::storage::Storage;
@@ -37,10 +39,9 @@ pub struct DoorBlock {
}
impl DoorBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -52,25 +53,7 @@ impl DoorBlock {
}
impl BlockLogic for DoorBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Boolean(false))
diff --git a/src/block/fluid.rs b/src/block/fluid.rs
index 55b0097..90289bc 100644
--- a/src/block/fluid.rs
+++ b/src/block/fluid.rs
@@ -2,9 +2,11 @@ use std::any::Any;
use std::error::Error;
use std::fmt;
-use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError};
-use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl};
+use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
use crate::block::transport::BridgeBlock;
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::content;
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
@@ -37,10 +39,9 @@ pub struct FluidBlock {
}
impl FluidBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -52,28 +53,10 @@ impl FluidBlock {
}
impl BlockLogic for FluidBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> {
- if config < 0 || config > u16::MAX as i32 {
+ if config < 0 || config > i32::from(u16::MAX) {
return Err(DataConvertError::Custom(Box::new(FluidConvertError(
config,
))));
diff --git a/src/block/logic.rs b/src/block/logic.rs
index ccfd8a0..43cf83b 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -10,7 +10,9 @@ use flate2::{
};
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::data::dynamic::{DynData, DynType};
use crate::data::{self, DataRead, DataWrite, GridPos};
use crate::item::storage::Storage;
@@ -35,10 +37,9 @@ pub struct MessageLogic {
}
impl MessageLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -50,25 +51,7 @@ impl MessageLogic {
}
impl BlockLogic for MessageLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -105,10 +88,9 @@ pub struct SwitchLogic {
}
impl SwitchLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -120,25 +102,7 @@ impl SwitchLogic {
}
impl BlockLogic for SwitchLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -156,7 +120,7 @@ impl BlockLogic for SwitchLogic {
}
fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> {
- Box::new(Self::get_state(state).clone())
+ Box::new(*Self::get_state(state))
}
fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {}
@@ -175,10 +139,9 @@ pub struct ProcessorLogic {
}
impl ProcessorLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -190,25 +153,7 @@ impl ProcessorLogic {
}
impl BlockLogic for ProcessorLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -216,7 +161,7 @@ impl BlockLogic for ProcessorLogic {
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> {
match data {
- DynData::Empty => Ok(Some(Self::create_state(ProcessorState::new()))),
+ DynData::Empty => Ok(Some(Self::create_state(ProcessorState::default()))),
DynData::ByteArray(arr) => {
let mut input = arr.as_ref();
let mut dec = Decompress::new(true);
@@ -257,7 +202,7 @@ impl BlockLogic for ProcessorLogic {
}
let code_len = ProcessorDeserializeError::forward(buff.read_i32())?;
- if code_len < 0 || code_len > 500 * 1024 {
+ if !(0..=500 * 1024).contains(&code_len) {
return Err(DeserializeError::Custom(Box::new(
ProcessorDeserializeError::CodeLength(code_len),
)));
@@ -298,7 +243,7 @@ impl BlockLogic for ProcessorLogic {
}
fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) {
- for link in Self::get_state_mut(state).links.iter_mut() {
+ for link in &mut Self::get_state_mut(state).links {
if horizontally {
link.x = -link.x;
}
@@ -309,7 +254,7 @@ impl BlockLogic for ProcessorLogic {
}
fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) {
- for link in Self::get_state_mut(state).links.iter_mut() {
+ for link in &mut Self::get_state_mut(state).links {
let (cdx, cdy) = link.get_pos();
link.x = if clockwise { cdy } else { -cdy };
link.y = if clockwise { -cdx } else { cdx };
@@ -318,14 +263,14 @@ impl BlockLogic for ProcessorLogic {
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> {
let state = Self::get_state(state);
- let mut rbuff = DataWrite::new();
+ let mut rbuff = DataWrite::default();
ProcessorSerializeError::forward(rbuff.write_u8(1))?;
assert!(state.code.len() < 500 * 1024);
ProcessorSerializeError::forward(rbuff.write_i32(state.code.len() as i32))?;
ProcessorSerializeError::forward(rbuff.write_bytes(state.code.as_bytes()))?;
assert!(state.links.len() < i32::MAX as usize);
ProcessorSerializeError::forward(rbuff.write_i32(state.links.len() as i32))?;
- for link in state.links.iter() {
+ for link in &state.links {
ProcessorSerializeError::forward(rbuff.write_utf(&link.name))?;
ProcessorSerializeError::forward(rbuff.write_i16(link.x))?;
ProcessorSerializeError::forward(rbuff.write_i16(link.y))?;
@@ -478,7 +423,7 @@ impl Error for ProcessorSerializeError {
}
}
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct ProcessorLink {
name: String,
x: i16,
@@ -486,10 +431,13 @@ pub struct ProcessorLink {
}
impl ProcessorLink {
+ #[must_use]
pub fn new(name: Cow<'_, str>, x: i16, y: i16) -> Self {
- if name.len() > u16::MAX as usize {
- panic!("name too long ({})", name.len());
- }
+ assert!(
+ u16::try_from(name.len()).is_ok(),
+ "name too long ({})",
+ name.len()
+ );
Self {
name: name.into_owned(),
x,
@@ -497,29 +445,25 @@ impl ProcessorLink {
}
}
+ #[must_use]
pub fn get_name(&self) -> &str {
&self.name
}
+ #[must_use]
pub fn get_pos(&self) -> (i16, i16) {
(self.x, self.y)
}
}
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct ProcessorState {
code: String,
links: Vec<ProcessorLink>,
}
impl ProcessorState {
- pub fn new() -> Self {
- Self {
- code: String::new(),
- links: Vec::new(),
- }
- }
-
+ #[must_use]
pub fn get_code(&self) -> &str {
&self.code
}
@@ -539,6 +483,7 @@ impl ProcessorState {
Ok(())
}
+ #[must_use]
pub fn get_links(&self) -> &[ProcessorLink] {
&self.links
}
@@ -552,8 +497,8 @@ impl ProcessorState {
if name.len() > u16::MAX as usize {
return Err(CreateError::NameLength(name.len()));
}
- for curr in self.links.iter() {
- if &name == &curr.name {
+ for curr in &self.links {
+ if name == curr.name {
return Err(CreateError::DuplicateName(name));
}
if x == curr.x && y == curr.y {
diff --git a/src/block/mod.rs b/src/block/mod.rs
index b3b7e11..aa8d2bb 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -43,6 +43,32 @@ pub trait BlockLogic {
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>;
}
+// i wish i could derive
+macro_rules! impl_block {
+ () => {
+ fn get_size(&self) -> u8 {
+ self.size
+ }
+
+ fn is_symmetric(&self) -> bool {
+ self.symmetric
+ }
+
+ fn create_build_cost(&self) -> Option<$crate::item::storage::Storage> {
+ if self.build_cost.is_empty() {
+ None
+ } else {
+ let mut storage = Storage::new();
+ for (ty, cnt) in self.build_cost {
+ storage.add(*ty, *cnt, u32::MAX);
+ }
+ Some(storage)
+ }
+ }
+ };
+}
+pub(crate) use impl_block;
+
#[derive(Debug)]
pub enum DataConvertError {
Custom(Box<dyn Error>),
@@ -145,6 +171,7 @@ pub struct Block {
}
impl Block {
+ #[must_use]
pub const fn new(
name: Cow<'static, str>,
logic: BoxAccess<'static, dyn BlockLogic + Sync>,
@@ -205,7 +232,7 @@ impl Block {
impl fmt::Debug for Block {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name: &str = &self.name;
- write!(f, "Block {{ name: {:?} }}", name)
+ write!(f, "Block {{ name: {name:?} }}")
}
}
@@ -224,6 +251,7 @@ pub enum Rotation {
}
impl Rotation {
+ #[must_use]
pub fn mirrored(self, horizontally: bool, vertically: bool) -> Self {
match self {
Self::Right => {
@@ -261,6 +289,7 @@ impl Rotation {
*self = self.mirrored(horizontally, vertically);
}
+ #[must_use]
pub fn rotated(self, clockwise: bool) -> Self {
match self {
Self::Right => {
@@ -298,6 +327,7 @@ impl Rotation {
*self = self.rotated(clockwise);
}
+ #[must_use]
pub fn rotated_180(self) -> Self {
match self {
Self::Right => Self::Left,
@@ -347,7 +377,7 @@ macro_rules! make_register
std::borrow::Cow::Borrowed($field), $crate::access::Access::Borrowed(&$logic));
)+
- pub fn register<'l>(reg: &mut $crate::block::BlockRegistry<'l>) {
+ pub fn register(reg: &mut $crate::block::BlockRegistry<'_>) {
$(assert!(reg.register(&[<$field:snake:upper>]).is_ok(), "duplicate block {:?}", $field);)+
}
}
@@ -355,13 +385,14 @@ macro_rules! make_register
}
pub(crate) use make_register;
+#[must_use]
pub fn build_registry() -> BlockRegistry<'static> {
- let mut reg = BlockRegistry::new();
+ let mut reg = BlockRegistry::default();
register(&mut reg);
reg
}
-pub fn register<'l>(reg: &mut BlockRegistry<'l>) {
+pub fn register(reg: &mut BlockRegistry<'_>) {
turret::register(reg);
extraction::register(reg);
transport::register(reg);
diff --git a/src/block/payload.rs b/src/block/payload.rs
index 9803d11..8339df3 100644
--- a/src/block/payload.rs
+++ b/src/block/payload.rs
@@ -4,7 +4,7 @@ use std::fmt;
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
use crate::block::{
- self, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+ self, impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
};
use crate::content;
use crate::data::dynamic::{DynData, DynType};
@@ -43,21 +43,16 @@ pub struct AssemblerBlock {
}
impl AssemblerBlock {
+ #[must_use]
pub const fn new(
size: u8,
symmetric: bool,
build_cost: BuildCost,
valid: &'static [unit::Type],
) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
- if valid.is_empty() {
- panic!("no valid units");
- }
- if valid.len() > i32::MAX as usize {
- panic!("too many valid units");
- }
+ assert!(size != 0, "invalid size");
+ assert!(!valid.is_empty(), "no valid units");
+ assert!(valid.len() <= i32::MAX as usize, "too many valid units");
Self {
size,
symmetric,
@@ -70,25 +65,7 @@ impl AssemblerBlock {
}
impl BlockLogic for AssemblerBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Int(-1))
@@ -186,10 +163,9 @@ pub struct PayloadBlock {
}
impl PayloadBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -201,25 +177,7 @@ impl PayloadBlock {
}
impl BlockLogic for PayloadBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
diff --git a/src/block/power.rs b/src/block/power.rs
index 3e152ef..e21d342 100644
--- a/src/block/power.rs
+++ b/src/block/power.rs
@@ -3,7 +3,9 @@ use std::error::Error;
use std::fmt;
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
use crate::item::storage::Storage;
@@ -39,13 +41,13 @@ pub struct ConnectorBlock {
}
impl ConnectorBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost, max: u8) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
- if max == 0 || max > i8::MAX as u8 {
- panic!("invalid maximum link count");
- }
+ assert!(size != 0, "invalid size");
+ assert!(
+ !(max == 0 || max > i8::MAX as u8),
+ "invalid maximum link count"
+ );
Self {
size,
symmetric,
@@ -54,6 +56,7 @@ impl ConnectorBlock {
}
}
+ #[must_use]
pub fn get_max_links(&self) -> u8 {
self.max
}
@@ -62,25 +65,7 @@ impl ConnectorBlock {
}
impl BlockLogic for ConnectorBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
diff --git a/src/block/simple.rs b/src/block/simple.rs
index 5e48510..e3d8db7 100644
--- a/src/block/simple.rs
+++ b/src/block/simple.rs
@@ -1,6 +1,6 @@
use std::any::{type_name, Any};
-use crate::block::{BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{impl_block, BlockLogic, DataConvertError, DeserializeError, SerializeError};
use crate::data::dynamic::DynData;
use crate::data::GridPos;
use crate::item;
@@ -10,13 +10,13 @@ macro_rules!state_impl
{
($vis:vis $type:ty) =>
{
- $vis fn get_state<'l>(state: &'l dyn Any) -> &'l $type
+ $vis fn get_state(state: &dyn Any) -> &$type
where Self: Sized
{
state.downcast_ref::<$type>().unwrap()
}
- $vis fn get_state_mut<'l>(state: &'l mut dyn Any) -> &'l mut $type
+ $vis fn get_state_mut(state: &mut dyn Any) -> &mut $type
where Self: Sized
{
state.downcast_mut::<$type>().unwrap()
@@ -40,10 +40,9 @@ pub struct SimpleBlock {
}
impl SimpleBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -53,25 +52,7 @@ impl SimpleBlock {
}
impl BlockLogic for SimpleBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -98,10 +79,8 @@ impl BlockLogic for SimpleBlock {
}
}
-macro_rules!cost
-{
- ($($item:ident: $cnt:literal),+) =>
- {
+macro_rules! cost {
+ ($($item:ident: $cnt:literal),+) => {
&[$((crate::item::Type::$item, $cnt)),*]
};
}
diff --git a/src/block/transport.rs b/src/block/transport.rs
index a889c71..1125ec5 100644
--- a/src/block/transport.rs
+++ b/src/block/transport.rs
@@ -3,15 +3,16 @@ use std::error::Error;
use std::fmt;
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::content;
use crate::data::dynamic::{DynData, DynType};
use crate::data::GridPos;
use crate::item;
use crate::item::storage::Storage;
-make_register!
-(
+make_register! {
"conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1));
"titanium-conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1, Lead: 1, Titanium: 1));
"plastanium-conveyor" => SimpleBlock::new(1, false, cost!(Graphite: 1, Silicon: 1, Plastanium: 1));
@@ -29,7 +30,7 @@ make_register!
// sandbox only
"item-source" => ItemBlock::new(1, true, &[]);
"item-void" => SimpleBlock::new(1, true, &[]);
-);
+}
pub struct ItemBlock {
size: u8,
@@ -38,10 +39,9 @@ pub struct ItemBlock {
}
impl ItemBlock {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -53,28 +53,10 @@ impl ItemBlock {
}
impl BlockLogic for ItemBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> {
- if config < 0 || config > u16::MAX as i32 {
+ if config < 0 || config > i32::from(u16::MAX) {
return Err(DataConvertError::Custom(Box::new(ItemConvertError(config))));
}
Ok(DynData::Content(content::Type::Item, config as u16))
@@ -178,6 +160,7 @@ pub struct BridgeBlock {
type Point2 = (i32, i32);
impl BridgeBlock {
+ #[must_use]
pub const fn new(
size: u8,
symmetric: bool,
@@ -185,12 +168,8 @@ impl BridgeBlock {
range: u16,
ortho: bool,
) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
- if range == 0 {
- panic!("invalid range");
- }
+ assert!(size != 0, "invalid size");
+ assert!(range != 0, "invalid range");
Self {
size,
symmetric,
@@ -204,25 +183,7 @@ impl BridgeBlock {
}
impl BlockLogic for BridgeBlock {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError> {
let (x, y) = ((config >> 16) as i16, config as i16);
@@ -232,8 +193,8 @@ impl BlockLogic for BridgeBlock {
y,
})));
}
- let dx = x as i32 - pos.0 as i32;
- let dy = y as i32 - pos.1 as i32;
+ let dx = i32::from(x) - i32::from(pos.0);
+ let dy = i32::from(y) - i32::from(pos.1);
Ok(DynData::Point2(dx, dy))
}
@@ -244,18 +205,11 @@ impl BlockLogic for BridgeBlock {
if self.ortho {
// the game uses (-worldX, -worldY) to indicate no target
// likely because the absolute target being (0, 0) means it's unlinked
- if dx != 0 {
- if dy != 0 {
- return Ok(Some(Self::create_state(None)));
- } else {
- if dx > self.range as i32 || dx < -(self.range as i32) {
- return Ok(Some(Self::create_state(None)));
- }
- }
- } else {
- if dy > self.range as i32 || dy < -(self.range as i32) {
- return Ok(Some(Self::create_state(None)));
- }
+ if dx != 0 && dy != 0 {
+ return Ok(Some(Self::create_state(None)));
+ }
+ if dx > i32::from(self.range) || dx < -i32::from(self.range) {
+ return Ok(Some(Self::create_state(None)));
}
}
// can't check range otherwise, it depends on the target's size
diff --git a/src/data/base64.rs b/src/data/base64.rs
index 895a362..1a39c0b 100644
--- a/src/data/base64.rs
+++ b/src/data/base64.rs
@@ -103,16 +103,12 @@ pub fn decode(input: &[u8], output: &mut [u8]) -> Result<usize, DecodeError> {
}
return Err(DecodeError::Truncated);
}
- let pad_len = if input.len() > 0 {
- if input[input.len() - 1] != PADDING {
- 0
- } else if input[input.len() - 2] != PADDING {
- 1
- } else {
- 2
- }
- } else {
+ let pad_len = if input.is_empty() || input[input.len() - 1] != PADDING {
0
+ } else if input[input.len() - 2] != PADDING {
+ 1
+ } else {
+ 2
};
let expect_len = input.len() / 4 * 3 - pad_len;
if output.len() < expect_len {
@@ -121,7 +117,9 @@ pub fn decode(input: &[u8], output: &mut [u8]) -> Result<usize, DecodeError> {
have: output.len(),
});
}
- if !input.is_empty() {
+ if input.is_empty() {
+ Ok(0)
+ } else {
let mut in_pos = 0usize;
let mut out_pos = 0usize;
while in_pos < input.len() - 4 {
@@ -172,8 +170,6 @@ pub fn decode(input: &[u8], output: &mut [u8]) -> Result<usize, DecodeError> {
"missed output ({out_pos}, expected {expect_len})"
);
Ok(out_pos)
- } else {
- Ok(0)
}
}
@@ -229,7 +225,7 @@ mod test {
assert_ne!(c0, PADDING, "padding character in data charset at {i}");
if i > 0 {
for (j, &c1) in CHARS[..i].iter().enumerate() {
- assert_ne!(c1, c0, "duplicate data character at {j} and {i}")
+ assert_ne!(c1, c0, "duplicate data character at {j} and {i}");
}
}
}
diff --git a/src/data/dynamic.rs b/src/data/dynamic.rs
index b1c4095..486eebc 100644
--- a/src/data/dynamic.rs
+++ b/src/data/dynamic.rs
@@ -33,6 +33,7 @@ pub enum DynData {
}
impl DynData {
+ #[must_use]
pub fn get_type(&self) -> DynType {
match self {
Self::Empty => DynType::Empty,
@@ -226,7 +227,7 @@ impl Serializer<DynData> for DynSerializer {
None => buff.write_bool(false)?,
Some(s) => {
buff.write_bool(true)?;
- buff.write_utf(s)?
+ buff.write_utf(s)?;
}
}
Ok(())
@@ -261,7 +262,7 @@ impl Serializer<DynData> for DynSerializer {
buff.write_u8(8)?;
buff.write_i8(arr.len() as i8)?;
for &(x, y) in arr.iter() {
- buff.write_i32(((x as i32) << 16) | ((y as i32) & 0xFFFF))?;
+ buff.write_i32((i32::from(x) << 16) | (i32::from(y) & 0xFFFF))?;
}
Ok(())
}
@@ -455,16 +456,13 @@ mod test {
};
}
- macro_rules!make_dyn_test
- {
- ($name:ident, $($val:expr),+) =>
- {
+ macro_rules! make_dyn_test {
+ ($name:ident, $($val:expr),+) => {
#[test]
- fn $name()
- {
+ fn $name() {
let input = [$($val),+];
let mut positions = [$(_zero!($val)),+];
- let mut writer = DataWrite::new();
+ let mut writer = DataWrite::default();
for (i, d) in input.iter().enumerate()
{
assert_eq!(DynSerializer.serialize(&mut writer, d), Ok(()));
@@ -496,27 +494,26 @@ mod test {
);
make_dyn_test!(
reparse_int,
- DynData::Int(581923),
- DynData::Int(2147483647),
- DynData::Int(-1047563850)
+ DynData::Int(581_923),
+ DynData::Int(2_147_483_647),
+ DynData::Int(-1_047_563_850)
);
make_dyn_test!(
reparse_long,
- DynData::Long(11295882949812),
- DynData::Long(-5222358074010407789)
+ DynData::Long(11_295_882_949_812),
+ DynData::Long(-5_222_358_074_010_407_789)
);
make_dyn_test!(
reparse_float,
- DynData::Float(3.14159265),
+ DynData::Float(std::f32::consts::PI),
DynData::Float(f32::INFINITY),
- DynData::Float(f32::EPSILON),
- DynData::Float(f32::NAN)
+ DynData::Float(f32::EPSILON)
);
make_dyn_test!(
reparse_string,
DynData::String(None),
DynData::String(Some("hello \u{10FE03}".to_string())),
- DynData::String(Some("".to_string()))
+ DynData::String(Some(String::new()))
);
make_dyn_test!(
reparse_content,
@@ -525,14 +522,14 @@ mod test {
);
make_dyn_test!(
reparse_int_array,
- DynData::IntArray(vec![581923, 2147483647, -1047563850]),
- DynData::IntArray(vec![1902864703])
+ DynData::IntArray(vec![581_923, 2_147_483_647, -1_047_563_850]),
+ DynData::IntArray(vec![1_902_864_703])
);
make_dyn_test!(
reparse_point2,
DynData::Point2(17, 0),
DynData::Point2(234, -345),
- DynData::Point2(-2147483648, -1)
+ DynData::Point2(-2_147_483_648, -1)
);
make_dyn_test!(
reparse_point2_array,
@@ -552,9 +549,8 @@ mod test {
);
make_dyn_test!(
reparse_double,
- DynData::Double(2.718281828459045),
- DynData::Double(-f64::INFINITY),
- DynData::Double(f64::NAN)
+ DynData::Double(std::f64::consts::E),
+ DynData::Double(-f64::INFINITY)
);
make_dyn_test!(
reparse_building,
@@ -582,7 +578,7 @@ mod test {
DynData::BoolArray(vec![true, true, true, false, true, false, true]),
DynData::BoolArray(vec![false, true])
);
- make_dyn_test!(reparse_unit, DynData::Unit(0), DynData::Unit(2147483647));
+ make_dyn_test!(reparse_unit, DynData::Unit(0), DynData::Unit(2_147_483_647));
make_dyn_test!(
reparse_vec2_array,
DynData::Vec2Array(vec![(4.4, 5.5), (-3.3, 6.6), (-2.2, -7.7)]),
diff --git a/src/data/mod.rs b/src/data/mod.rs
index cf1b19f..fa332a4 100644
--- a/src/data/mod.rs
+++ b/src/data/mod.rs
@@ -30,7 +30,7 @@ macro_rules! make_read {
}
impl<'d> DataRead<'d> {
- pub fn new(data: &'d [u8]) -> Self {
+ #[must_use] pub fn new(data: &'d [u8]) -> Self {
Self { data }
}
@@ -172,7 +172,7 @@ macro_rules! make_write {
impl<'d> DataWrite<'d> {
pub fn write_bool(&mut self, val: bool) -> Result<(), WriteError> {
- self.write_u8(val as u8)
+ self.write_u8(u8::from(val))
}
make_write!(write_u8, u8);
@@ -202,23 +202,20 @@ impl<'d> DataWrite<'d> {
Ok(())
}
- pub fn is_owned(&self) -> bool {
- match self.data {
- WriteBuff::Vec(..) => true,
- _ => false,
- }
+ #[must_use] pub fn is_owned(&self) -> bool {
+ matches!(self.data, WriteBuff::Vec(..))
}
- pub fn get_written(&self) -> &[u8] {
+ #[must_use] pub fn get_written(&self) -> &[u8] {
match &self.data {
WriteBuff::Ref { raw, pos } => &raw[..*pos],
- WriteBuff::Vec(v) => &v,
+ WriteBuff::Vec(v) => v,
}
}
}
-impl DataWrite<'static> {
- pub fn new() -> Self {
+impl Default for DataWrite<'static> {
+ fn default() -> Self {
Self {
data: WriteBuff::Vec(Vec::new()),
}
@@ -291,7 +288,7 @@ impl From<u32> for GridPos {
impl From<GridPos> for u32 {
fn from(value: GridPos) -> Self {
- ((value.0 as u32) << 16) | (value.1 as u32)
+ (u32::from(value.0) << 16) | u32::from(value.1)
}
}
@@ -308,26 +305,26 @@ mod test {
assert_eq!(read.read_u16(), Ok(43296));
assert_eq!(read.read_i16(), Ok(29123));
assert_eq!(read.read_i16(), Ok(-17559));
- assert_eq!(read.read_i32(), Ok(1667965152));
- assert_eq!(read.read_i32(), Ok(-1433832849));
- assert_eq!(read.read_i64(), Ok(8605851562280493296));
- assert_eq!(read.read_i64(), Ok(-6942694510468635278));
+ assert_eq!(read.read_i32(), Ok(1_667_965_152));
+ assert_eq!(read.read_i32(), Ok(-1_433_832_849));
+ assert_eq!(read.read_i64(), Ok(8_605_851_562_280_493_296));
+ assert_eq!(read.read_i64(), Ok(-6_942_694_510_468_635_278));
assert_eq!(read.read_utf(), Ok("the lazy dog."));
}
#[test]
fn write() {
- let mut write = DataWrite::new();
+ let mut write = DataWrite::default();
assert_eq!(write.write_u8(84), Ok(()));
assert_eq!(write.write_i8(104), Ok(()));
assert_eq!(write.write_i8(-61), Ok(()));
assert_eq!(write.write_u16(43296), Ok(()));
assert_eq!(write.write_i16(29123), Ok(()));
assert_eq!(write.write_i16(-17559), Ok(()));
- assert_eq!(write.write_i32(1667965152), Ok(()));
- assert_eq!(write.write_i32(-1433832849), Ok(()));
- assert_eq!(write.write_i64(8605851562280493296), Ok(()));
- assert_eq!(write.write_i64(-6942694510468635278), Ok(()));
+ assert_eq!(write.write_i32(1_667_965_152), Ok(()));
+ assert_eq!(write.write_i32(-1_433_832_849), Ok(()));
+ assert_eq!(write.write_i64(8_605_851_562_280_493_296), Ok(()));
+ assert_eq!(write.write_i64(-6_942_694_510_468_635_278), Ok(()));
assert_eq!(write.write_utf("the lazy dog."), Ok(()));
assert_eq!(
write.get_written(),
diff --git a/src/data/schematic.rs b/src/data/schematic.rs
index 6331606..a3b104d 100644
--- a/src/data/schematic.rs
+++ b/src/data/schematic.rs
@@ -29,14 +29,17 @@ pub struct Placement<'l> {
}
impl<'l> Placement<'l> {
+ #[must_use]
pub fn get_pos(&self) -> GridPos {
self.pos
}
+ #[must_use]
pub fn get_block(&self) -> &'l Block {
self.block
}
+ #[must_use]
pub fn get_state(&self) -> Option<&dyn Any> {
match self.state {
None => None,
@@ -59,6 +62,7 @@ impl<'l> Placement<'l> {
Ok(std::mem::replace(&mut self.state, state))
}
+ #[must_use]
pub fn get_rotation(&self) -> Rotation {
self.rot
}
@@ -93,6 +97,7 @@ pub struct Schematic<'l> {
}
impl<'l> Schematic<'l> {
+ #[must_use]
pub fn new(width: u16, height: u16) -> Self {
match Self::try_new(width, height) {
Ok(s) => s,
@@ -121,14 +126,17 @@ impl<'l> Schematic<'l> {
})
}
+ #[must_use]
pub fn get_width(&self) -> u16 {
self.width
}
+ #[must_use]
pub fn get_height(&self) -> u16 {
self.height
}
+ #[must_use]
pub fn get_tags(&self) -> &HashMap<String, String> {
&self.tags
}
@@ -137,16 +145,19 @@ impl<'l> Schematic<'l> {
&mut self.tags
}
+ #[must_use]
pub fn is_empty(&self) -> bool {
self.blocks.is_empty()
}
+ #[must_use]
pub fn get_block_count(&self) -> usize {
self.blocks.len()
}
+ #[must_use]
pub fn is_region_empty(&self, x: u16, y: u16, w: u16, h: u16) -> bool {
- if self.blocks.len() == 0 {
+ if self.blocks.is_empty() {
return true;
}
if x >= self.width || y >= self.height || w == 0 || h == 0 {
@@ -188,7 +199,7 @@ impl<'l> Schematic<'l> {
h: self.height,
});
}
- if self.blocks.len() == 0 {
+ if self.blocks.is_empty() {
return Ok(None);
}
let pos = (x as usize) + (y as usize) * (self.width as usize);
@@ -207,7 +218,7 @@ impl<'l> Schematic<'l> {
h: self.height,
});
}
- if self.blocks.len() == 0 {
+ if self.blocks.is_empty() {
return Ok(None);
}
let pos = (x as usize) + (y as usize) * (self.width as usize);
@@ -240,12 +251,12 @@ impl<'l> Schematic<'l> {
}
fn fill_lookup(&mut self, x: usize, y: usize, sz: usize, val: Option<usize>) {
- if self.lookup.len() == 0 {
+ if self.lookup.is_empty() {
self.lookup
.resize((self.width as usize) * (self.height as usize), None);
}
if sz > 1 {
- let off = ((sz - 1) / 2) as usize;
+ let off = (sz - 1) / 2;
let (x0, y0) = (x - off, y - off);
for dy in 0..sz {
for dx in 0..sz {
@@ -265,7 +276,7 @@ impl<'l> Schematic<'l> {
data: DynData,
rot: Rotation,
) -> Result<&Placement<'l>, PlaceError> {
- let sz = block.get_size() as u16;
+ let sz = u16::from(block.get_size());
let off = (sz - 1) / 2;
if x < off || y < off {
return Err(PlaceError::Bounds {
@@ -310,7 +321,7 @@ impl<'l> Schematic<'l> {
rot: Rotation,
collect: bool,
) -> Result<Option<Vec<Placement<'l>>>, PlaceError> {
- let sz = block.get_size() as u16;
+ let sz = u16::from(block.get_size());
let off = (sz - 1) / 2;
if x < off || y < off {
return Err(PlaceError::Bounds {
@@ -403,20 +414,20 @@ impl<'l> Schematic<'l> {
h: self.height,
});
}
- if self.blocks.len() > 0 {
+ if self.blocks.is_empty() {
+ Ok(None)
+ } else {
let pos = (x as usize) + (y as usize) * (self.width as usize);
match self.lookup[pos] {
None => Ok(None),
Some(idx) => Ok(Some(self.swap_remove(idx))),
}
- } else {
- Ok(None)
}
}
fn rebuild_lookup(&mut self) {
self.lookup.clear();
- if self.blocks.len() > 0 {
+ if !self.blocks.is_empty() {
self.lookup
.resize((self.width as usize) * (self.height as usize), None);
for (i, curr) in self.blocks.iter().enumerate() {
@@ -438,9 +449,9 @@ impl<'l> Schematic<'l> {
pub fn mirror(&mut self, horizontally: bool, vertically: bool) {
if !self.blocks.is_empty() && (horizontally || vertically) {
- for curr in self.blocks.iter_mut() {
+ for curr in &mut self.blocks {
// because position is the bottom left of the center (which changes during mirroring)
- let shift = (curr.block.get_size() as u16 - 1) % 2;
+ let shift = (u16::from(curr.block.get_size()) - 1) % 2;
if horizontally {
curr.pos.0 = self.width - 1 - curr.pos.0 - shift;
}
@@ -465,11 +476,11 @@ impl<'l> Schematic<'l> {
self.width = h;
self.height = w;
if !self.blocks.is_empty() {
- for curr in self.blocks.iter_mut() {
+ for curr in &mut self.blocks {
let x = curr.pos.0;
let y = curr.pos.1;
// because position is the bottom left of the center (which changes during rotation)
- let shift = (curr.block.get_size() as u16 - 1) % 2;
+ let shift = (u16::from(curr.block.get_size()) - 1) % 2;
if clockwise {
curr.pos.0 = y;
curr.pos.1 = w - 1 - x - shift;
@@ -518,8 +529,8 @@ impl<'l> Schematic<'l> {
let top_bound = dy + h as i16 - 1;
let left_bound = dx;
let bottom_bound = dy;
- for Placement { pos, block, .. } in self.blocks.iter() {
- let sz = block.get_size() as u16;
+ for Placement { pos, block, .. } in &self.blocks {
+ let sz = u16::from(block.get_size());
let (x0, y0, x1, y1) = (
pos.0 - (sz - 1) / 2,
pos.1 - (sz - 1) / 2,
@@ -539,7 +550,7 @@ impl<'l> Schematic<'l> {
bottom = bottom_bound as u16 - y0;
}
}
- if left > 0 || top > 0 || left > 0 || bottom > 0 {
+ if left > 0 || top > 0 || right > 0 || bottom > 0 {
return Err(ResizeError::Truncated {
right,
top,
@@ -549,7 +560,7 @@ impl<'l> Schematic<'l> {
}
self.width = w;
self.height = h;
- for Placement { pos, .. } in self.blocks.iter_mut() {
+ for Placement { pos, .. } in &mut self.blocks {
pos.0 = (pos.0 as i16 + dx) as u16;
pos.1 = (pos.1 as i16 + dy) as u16;
}
@@ -560,6 +571,7 @@ impl<'l> Schematic<'l> {
self.mirror(true, true);
}
+ #[must_use]
pub fn pos_iter(&self) -> PosIter {
PosIter {
x: 0,
@@ -573,10 +585,11 @@ impl<'l> Schematic<'l> {
self.blocks.iter()
}
+ #[must_use]
pub fn compute_total_cost(&self) -> (ItemStorage, bool) {
let mut cost = ItemStorage::new();
let mut sandbox = false;
- for &Placement { block, .. } in self.blocks.iter() {
+ for &Placement { block, .. } in &self.blocks {
if let Some(curr) = block.get_build_cost() {
cost.add_all(curr, u32::MAX);
} else {
@@ -753,7 +766,7 @@ impl<'l> fmt::Display for Schematic<'l> {
// find unique letters for each block, more common blocks pick first
let mut name_cnt = HashMap::<&str, u16>::new();
- for p in self.blocks.iter() {
+ for p in &self.blocks {
match name_cnt.entry(p.block.get_name()) {
Entry::Occupied(mut e) => *e.get_mut() += 1,
Entry::Vacant(e) => {
@@ -770,7 +783,7 @@ impl<'l> fmt::Display for Schematic<'l> {
0x70u8, 0x00u8, 0x00u8, 0x40u8, 0x90u8,
];
let mut types = HashMap::<&str, char>::new();
- for &(name, _) in name_cnt.iter() {
+ for &(name, _) in &name_cnt {
let mut found = false;
for c in name.chars() {
if c > ' ' && c <= '~' {
@@ -807,7 +820,9 @@ impl<'l> fmt::Display for Schematic<'l> {
}
// coordinates start in the bottom left, so y starts at self.height - 1
- if self.blocks.len() > 0 {
+ if self.blocks.is_empty() {
+ write!(f, "<empty {} * {}>", self.width, self.height)?;
+ } else {
for y in (0..self.height as usize).rev() {
let mut x = 0usize;
while x < self.width as usize {
@@ -902,8 +917,6 @@ impl<'l> fmt::Display for Schematic<'l> {
let v = *types.get(k).unwrap();
write!(f, "\n({v}) {k}")?;
}
- } else {
- write!(f, "<empty {} * {}>", self.width, self.height)?;
}
Ok(())
}
@@ -1007,7 +1020,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
buff.write_u32(SCHEMATIC_HEADER)?;
buff.write_u8(1)?;
- let mut rbuff = DataWrite::new();
+ let mut rbuff = DataWrite::default();
// don't have to check dimensions because they're already limited to MAX_DIMENSION
rbuff.write_i16(data.width as i16)?;
rbuff.write_i16(data.height as i16)?;
@@ -1015,20 +1028,17 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
return Err(WriteError::TagCount(data.tags.len()));
}
rbuff.write_u8(data.tags.len() as u8)?;
- for (k, v) in data.tags.iter() {
+ for (k, v) in &data.tags {
rbuff.write_utf(k)?;
rbuff.write_utf(v)?;
}
// use string keys here to avoid issues with different block refs with the same name
let mut block_map = HashMap::<&str, u32>::new();
let mut block_table = Vec::<&str>::new();
- for curr in data.blocks.iter() {
- match block_map.entry(curr.block.get_name()) {
- Entry::Vacant(e) => {
- e.insert(block_table.len() as u32);
- block_table.push(curr.block.get_name());
- }
- _ => (),
+ for curr in &data.blocks {
+ if let Entry::Vacant(e) = block_map.entry(curr.block.get_name()) {
+ e.insert(block_table.len() as u32);
+ block_table.push(curr.block.get_name());
}
}
if block_table.len() > i8::MAX as usize {
@@ -1036,13 +1046,13 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
}
// else: implies contents are also valid i8 (they're strictly less than the map length)
rbuff.write_i8(block_table.len() as i8)?;
- for &name in block_table.iter() {
+ for &name in &block_table {
rbuff.write_utf(name)?;
}
// don't have to check data.blocks.len() because dimensions don't allow exceeding MAX_BLOCKS
rbuff.write_i32(data.blocks.len() as i32)?;
let mut num = 0;
- for curr in data.blocks.iter() {
+ for curr in &data.blocks {
rbuff.write_i8(block_map[curr.block.get_name()] as i8)?;
rbuff.write_u32(u32::from(curr.pos))?;
let data = match curr.state {
@@ -1056,10 +1066,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
assert_eq!(num, data.blocks.len());
// compress into the provided buffer
- let raw = match rbuff.data {
- data::WriteBuff::Vec(v) => v,
- _ => unreachable!("write buffer not owned"),
- };
+ let data::WriteBuff::Vec(raw) = rbuff.data else { unreachable!("write buffer not owned") };
let mut comp = Compress::new(Compression::default(), true);
// compress the immediate buffer into a temp buffer to copy it to buff? no thanks
match buff.data {
@@ -1261,11 +1268,11 @@ impl<'l> SchematicSerializer<'l> {
}
pub fn serialize_base64(&mut self, data: &Schematic<'l>) -> Result<String, W64Error> {
- let mut buff = DataWrite::new();
+ let mut buff = DataWrite::default();
self.serialize(&mut buff, data)?;
let buff = buff.get_written();
// round up because of padding
- let required = 4 * (buff.len() / 3 + if buff.len() % 3 != 0 { 1 } else { 0 });
+ let required = 4 * (buff.len() / 3 + usize::from(buff.len() % 3 != 0));
let mut text = Vec::<u8>::new();
text.resize(required, 0);
let n_out = base64::encode(buff, text.as_mut())?;
diff --git a/src/exe/args.rs b/src/exe/args.rs
index f037c12..46f8a42 100644
--- a/src/exe/args.rs
+++ b/src/exe/args.rs
@@ -86,13 +86,11 @@ where
return Err(Error::EmptyName { pos: arg_off + pos });
}
}
- } else {
- if let Err(val) = handler.on_literal(arg) {
- return Err(Error::Handler {
- pos: arg_off + pos,
- val,
- });
- }
+ } else if let Err(val) = handler.on_literal(arg) {
+ return Err(Error::Handler {
+ pos: arg_off + pos,
+ val,
+ });
}
}
}
@@ -113,17 +111,11 @@ pub enum ArgCount {
impl ArgCount {
pub const fn has_value(&self) -> bool {
- match self {
- Self::Optional(..) | ArgCount::Required(..) => true,
- _ => false,
- }
+ matches!(self, Self::Optional(..) | ArgCount::Required(..))
}
pub const fn is_required(&self) -> bool {
- match self {
- Self::Required(..) => true,
- _ => false,
- }
+ matches!(self, Self::Required(..))
}
pub const fn get_max_count(&self) -> Option<usize> {
@@ -196,25 +188,15 @@ pub enum OptionValue {
impl OptionValue {
pub const fn is_absent(&self) -> bool {
- match self {
- Self::Absent => true,
- _ => false,
- }
+ matches!(self, Self::Absent)
}
pub const fn is_present(&self) -> bool {
- match self {
- Self::Present | Self::Value(..) | Self::Values(..) => true,
- _ => false,
- }
+ matches!(self, Self::Present | Self::Value(..) | Self::Values(..))
}
pub const fn has_value(&self) -> bool {
- match self {
- Self::Value(..) => true,
- Self::Values(..) => true,
- _ => false,
- }
+ matches!(self, Self::Value(..) | Self::Values(..))
}
pub const fn get_value(&self) -> Option<&String> {
@@ -233,7 +215,7 @@ impl OptionValue {
}
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Default)]
pub struct OptionHandler {
options: Vec<(ArgOption, OptionValue)>,
short_map: HashMap<char, usize>,
@@ -242,39 +224,23 @@ pub struct OptionHandler {
}
impl OptionHandler {
- pub fn new() -> Self {
- Self {
- options: Vec::new(),
- short_map: HashMap::new(),
- long_map: HashMap::new(),
- literals: Vec::new(),
- }
- }
-
pub fn add(&mut self, opt: ArgOption) -> Result<OptionRef, AddArgError> {
- match opt.short {
- Some(c) => match self.short_map.get(&c) {
- Some(&i) => {
- return Err(AddArgError {
- to_add: opt,
- existing: &self.options[i].0,
- })
- }
- _ => (),
- },
- _ => (),
+ if let Some(c) = opt.short {
+ if let Some(&i) = self.short_map.get(&c) {
+ return Err(AddArgError {
+ to_add: opt,
+ existing: &self.options[i].0,
+ });
+ }
}
- match opt.long {
- Some(ref s) => match self.long_map.get(&**s) {
- Some(&i) => {
- return Err(AddArgError {
- to_add: opt,
- existing: &self.options[i].0,
- })
- }
- _ => (),
- },
- _ => (),
+
+ if let Some(ref s) = opt.long {
+ if let Some(&i) = self.long_map.get(&**s) {
+ return Err(AddArgError {
+ to_add: opt,
+ existing: &self.options[i].0,
+ });
+ }
}
let idx = self.options.len();
@@ -323,7 +289,7 @@ impl OptionHandler {
let (ref o, ref mut curr) = self.options[idx];
match o.count {
ArgCount::Forbidden => {
- if let None = value {
+ if value.is_none() {
if curr.is_absent() {
*curr = OptionValue::Present;
}
diff --git a/src/exe/edit.rs b/src/exe/edit.rs
index d89e0b2..80a1506 100644
--- a/src/exe/edit.rs
+++ b/src/exe/edit.rs
@@ -22,7 +22,7 @@ struct State<'l> {
}
pub fn main(mut args: Args, arg_off: usize) {
- let mut handler = OptionHandler::new();
+ let mut handler = OptionHandler::default();
let opt_file = handler
.add(ArgOption::new(
Some('f'),
@@ -99,7 +99,7 @@ pub fn main(mut args: Args, arg_off: usize) {
// give the user a chance to save their work
if state.unsaved {
- let mut data = DataWrite::new();
+ let mut data = DataWrite::default();
match ss.serialize(&mut data, state.schematic.as_ref().unwrap()) {
Ok(()) => {
let data = data.get_written();
@@ -153,7 +153,7 @@ impl<'l> Tokenizer<'l> {
self.skip_ws();
if let Some(curr) = self.0 {
if curr.len() >= 2 && (curr.as_bytes()[0] == b'"' || curr.as_bytes()[0] == b'\'') {
- match (&curr[1..]).find(curr.as_bytes()[0] as char) {
+ match (curr[1..]).find(curr.as_bytes()[0] as char) {
None => {
self.0 = None;
Some(&curr[1..])
@@ -319,7 +319,7 @@ macro_rules! parse_num {
$cmd.print_usage(0);
return;
}
- Some(s) => match <$type>::from_str_radix(s, 10) {
+ Some(s) => match s.parse::<$type>() {
Ok(v) => v,
Err(e) => {
print_err!(e, "Could not parse {}", $name);
@@ -508,7 +508,6 @@ fn interpret(state: &mut State, cmd: &str) {
};
if let Some(e) = result {
print_err!(e, "Failed to place block at {x} / {y}");
- return;
}
}
Some("rotate") => {
@@ -793,7 +792,7 @@ fn interpret(state: &mut State, cmd: &str) {
Command::Save.print_usage(0);
return;
}
- let mut serial_buff = DataWrite::new();
+ let mut serial_buff = DataWrite::default();
if let Err(e) = SchematicSerializer(state.reg).serialize(&mut serial_buff, schematic) {
print_err!(e, "Could not serialize schematic");
return;
@@ -1238,7 +1237,6 @@ fn interpret_sub(state: &mut State, tokens: &mut Tokenizer) {
};
if let Some(e) = result {
print_err!(e, "Failed to place block at {x} / {y}");
- return;
}
}
Some("rotate") => {
diff --git a/src/exe/print.rs b/src/exe/print.rs
index 9a7faae..d1b79c5 100644
--- a/src/exe/print.rs
+++ b/src/exe/print.rs
@@ -11,7 +11,7 @@ use crate::args::{self, ArgCount, ArgOption, OptionHandler};
use crate::print_err;
pub fn main(mut args: Args, arg_off: usize) {
- let mut handler = OptionHandler::new();
+ let mut handler = OptionHandler::default();
let opt_file = handler
.add(ArgOption::new(
Some('f'),
diff --git a/src/item/storage.rs b/src/item/storage.rs
index fd5be32..e6ec368 100644
--- a/src/item/storage.rs
+++ b/src/item/storage.rs
@@ -12,6 +12,7 @@ pub struct Storage {
}
impl Storage {
+ #[must_use]
pub const fn new() -> Self {
Self {
base: Vec::new(),
@@ -19,14 +20,17 @@ impl Storage {
}
}
+ #[must_use]
pub fn is_empty(&self) -> bool {
self.total == 0
}
+ #[must_use]
pub fn get_total(&self) -> u64 {
self.total
}
+ #[must_use]
pub fn get(&self, ty: item::Type) -> u32 {
match self.base.get(u16::from(ty) as usize) {
None => 0,
@@ -40,12 +44,12 @@ impl Storage {
None => {
self.base.resize(idx + 1, 0);
self.base[idx] = count;
- self.total += count as u64;
+ self.total += u64::from(count);
0
}
Some(curr) => {
let prev = *curr;
- self.total = self.total - prev as u64 + count as u64;
+ self.total = self.total - u64::from(prev) + u64::from(count);
*curr = count;
prev
}
@@ -59,14 +63,14 @@ impl Storage {
let actual = add.min(max);
self.base.resize(idx + 1, 0);
self.base[idx] = actual;
- self.total += add as u64;
+ self.total += u64::from(add);
(actual, actual)
}
Some(curr) => {
if *curr < max {
let actual = add.min(max - *curr);
*curr += actual;
- self.total += actual as u64;
+ self.total += u64::from(actual);
(actual, *curr)
} else {
(0, *curr)
@@ -87,7 +91,7 @@ impl Storage {
if add <= max {
self.base.resize(idx + 1, 0);
self.base[idx] = add;
- self.total += add as u64;
+ self.total += u64::from(add);
Ok((add, add))
} else {
Err(TryAddError {
@@ -101,7 +105,7 @@ impl Storage {
Some(curr) => {
if *curr <= max && max - *curr <= add {
*curr += add;
- self.total += add as u64;
+ self.total += u64::from(add);
Ok((add, *curr))
} else {
Err(TryAddError {
@@ -122,7 +126,7 @@ impl Storage {
if *curr > min {
let actual = sub.min(*curr - min);
*curr -= actual;
- self.total -= actual as u64;
+ self.total -= u64::from(actual);
(actual, *curr)
} else {
(0, *curr)
@@ -148,7 +152,7 @@ impl Storage {
Some(curr) => {
if *curr >= min && *curr - min >= sub {
*curr -= sub;
- self.total -= sub as u64;
+ self.total -= u64::from(sub);
Ok((sub, *curr))
} else {
Err(TrySubError {
@@ -177,7 +181,7 @@ impl Storage {
if curr < max_each {
let actual = (*add).min(max_each - curr);
self.base[idx] += actual;
- added += actual as u64;
+ added += u64::from(actual);
}
}
// process the final element (which we've retrieved first)
@@ -185,7 +189,7 @@ impl Storage {
if curr < max_each {
let actual = (*add_last).min(max_each - curr);
self.base[last] += actual;
- added += actual as u64;
+ added += u64::from(actual);
}
// update total
self.total += added;
@@ -209,7 +213,7 @@ impl Storage {
let actual = (*add).min(max_each - curr);
self.base[idx] += actual;
*add -= actual;
- added += actual as u64;
+ added += u64::from(actual);
}
}
// process the final element (which we've retrieved first)
@@ -218,7 +222,7 @@ impl Storage {
let actual = (*add_last).min(max_each - curr);
self.base[last] += actual;
*add_last -= actual;
- added += actual as u64;
+ added += u64::from(actual);
}
// update totals
self.total += added;
@@ -237,7 +241,7 @@ impl Storage {
if *curr > min_each {
let actual = (*sub).min(*curr - min_each);
self.base[idx] -= actual;
- subbed += actual as u64;
+ subbed += u64::from(actual);
}
} else {
break;
@@ -258,12 +262,12 @@ impl Storage {
let lhs = &mut self.base[..end];
let rhs = &mut other.base[..end];
// process items by increasing ID
- for (l, r) in lhs.into_iter().zip(rhs) {
+ for (l, r) in lhs.iter_mut().zip(rhs) {
if *l > min_each && *r > min_each {
let actual = (*l - min_each).min(*r - min_each);
*l -= actual;
*r -= actual;
- subbed -= actual as u64;
+ subbed -= u64::from(actual);
}
}
// update totals
@@ -273,14 +277,16 @@ impl Storage {
(subbed, self.total, other.total)
}
- pub fn iter<'s>(&'s self) -> Iter<'s> {
+ #[must_use]
+ pub fn iter(&self) -> Iter<'_> {
Iter {
base: self.base.iter().enumerate(),
all: true,
}
}
- pub fn iter_nonzero<'s>(&'s self) -> Iter<'s> {
+ #[must_use]
+ pub fn iter_nonzero(&self) -> Iter<'_> {
Iter {
base: self.base.iter().enumerate(),
all: false,
@@ -288,7 +294,7 @@ impl Storage {
}
pub fn clear(&mut self) {
- self.base.clear()
+ self.base.clear();
}
}
@@ -375,7 +381,7 @@ impl<'l> Iterator for Iter<'l> {
type Item = (item::Type, u32);
fn next(&mut self) -> Option<Self::Item> {
- while let Some((idx, cnt)) = self.base.next() {
+ for (idx, cnt) in self.base.by_ref() {
if *cnt > 0 || self.all {
if let Ok(ty) = item::Type::try_from(idx as u16) {
return Some((ty, *cnt));
diff --git a/src/logic/mod.rs b/src/logic/mod.rs
index cd9ba52..967ca22 100644
--- a/src/logic/mod.rs
+++ b/src/logic/mod.rs
@@ -23,7 +23,7 @@ macro_rules!match_select
}
impl LogicField {
- pub fn is_readable(&self) -> bool {
+ #[must_use] pub fn is_readable(&self) -> bool {
match_select!(
self,
LogicField,
@@ -73,7 +73,7 @@ impl LogicField {
)
}
- pub fn is_writable(&self) -> bool {
+ #[must_use] pub fn is_writable(&self) -> bool {
match_select!(self, LogicField, Enabled, Shoot, ShootP, Config, Color)
}
}
diff --git a/src/registry.rs b/src/registry.rs
index 240fb65..938836a 100644
--- a/src/registry.rs
+++ b/src/registry.rs
@@ -12,22 +12,24 @@ pub struct Registry<'l, E: RegistryEntry + fmt::Debug + 'static> {
by_name: HashMap<&'l str, &'l E>,
}
-impl<'l, E: RegistryEntry + fmt::Debug + 'static> Registry<'l, E> {
- pub fn new() -> Self {
+impl<'l, E: RegistryEntry + fmt::Debug + 'static> Default for Registry<'l, E> {
+ fn default() -> Self {
Self {
by_name: HashMap::new(),
}
}
+}
+impl<'l, E: RegistryEntry + fmt::Debug + 'static> Registry<'l, E> {
pub fn register(&mut self, val: &'l E) -> Result<&'l E, RegisterError<'l, E>> {
- match self.by_name.entry(&val.get_name()) {
+ match self.by_name.entry(val.get_name()) {
Entry::Occupied(e) => Err(RegisterError(e.get())),
Entry::Vacant(e) => Ok(e.insert(val)),
}
}
- pub fn get(&self, name: &str) -> Option<&'l E> {
- self.by_name.get(name).map(|&r| r)
+ #[must_use] pub fn get(&self, name: &str) -> Option<&'l E> {
+ self.by_name.get(name).copied()
}
}
diff --git a/src/team.rs b/src/team.rs
index d6f32fc..1c0e4f1 100644
--- a/src/team.rs
+++ b/src/team.rs
@@ -7,11 +7,11 @@ use crate::content::{Content, Type};
pub struct Team(u8);
impl Team {
- pub fn of(id: u8) -> Self {
+ #[must_use] pub fn of(id: u8) -> Self {
Self(id)
}
- pub fn is_base(&self) -> bool {
+ #[must_use] pub fn is_base(&self) -> bool {
self.0 < 6
}
}
@@ -26,7 +26,7 @@ impl TryFrom<u16> for Team {
type Error = TryFromU16Error;
fn try_from(value: u16) -> Result<Self, Self::Error> {
- if value <= u8::MAX as u16 {
+ if u8::try_from(value).is_ok() {
Ok(Team(value as u8))
} else {
Err(TryFromU16Error(value))
@@ -45,7 +45,7 @@ impl From<Team> for u8 {
impl From<Team> for u16 {
fn from(value: Team) -> Self {
- value.0 as u16
+ u16::from(value.0)
}
}
@@ -79,7 +79,7 @@ impl Content for Team {
}
fn get_id(&self) -> u16 {
- self.0 as u16
+ u16::from(self.0)
}
fn get_name(&self) -> &'static str {
@@ -93,7 +93,7 @@ impl Content for Team {
// dark magic: offsets manually computed, then rely on the format "...|team#{i}|..."
i @ 6..=9 => {
// length: 7 ("team#" (5) + 1 digit + "|" (1))
- let s = 0 + ((i - 6) as usize) * 7;
+ let s = ((i - 6) as usize) * 7;
&TEAM_NAMES[s..s + 6] // exclude the trailing "|"
}
i @ 10..=99 => {
diff --git a/src/utils/once_cell.rs b/src/utils/once_cell.rs
index 4bfd3eb..9dda9ff 100644
--- a/src/utils/once_cell.rs
+++ b/src/utils/once_cell.rs
@@ -13,6 +13,7 @@ pub struct OnceCell<T> {
}
impl<T> OnceCell<T> {
+ #[must_use]
pub const fn new() -> Self {
Self {
value: UnsafeCell::new(MaybeUninit::uninit()),
@@ -30,7 +31,7 @@ impl<T> OnceCell<T> {
pub fn get(&self) -> Option<&T> {
if self.state.load(Ordering::Acquire) == STATE_READY {
// SAFETY: won't be overwritten for the lifetime of this reference
- Some(unsafe { (&*self.value.get()).assume_init_ref() })
+ Some(unsafe { (*self.value.get()).assume_init_ref() })
} else {
None
}
@@ -41,7 +42,7 @@ impl<T> OnceCell<T> {
match self.state.load(Ordering::Acquire) {
STATE_INIT => return None,
STATE_LOCKED => (), // continue
- STATE_READY => return Some(unsafe { (&*self.value.get()).assume_init_ref() }),
+ STATE_READY => return Some(unsafe { (*self.value.get()).assume_init_ref() }),
x => unreachable!("invalid state {x}"),
}
}
@@ -61,7 +62,7 @@ impl<T> OnceCell<T> {
self.state.store(STATE_READY, Ordering::Release);
return written;
}
- Err(STATE_READY) => return unsafe { (&*self.value.get()).assume_init_ref() },
+ Err(STATE_READY) => return unsafe { (*self.value.get()).assume_init_ref() },
Err(..) => (), // locked or spurious failure
}
}
@@ -82,7 +83,7 @@ impl<T> OnceCell<T> {
Ok(written)
}
// SAFETY: guaranteed to be initialized & protected by acquire ordering
- Err(STATE_READY) => return Ok(unsafe { (&*self.value.get()).assume_init_ref() }),
+ Err(STATE_READY) => return Ok(unsafe { (*self.value.get()).assume_init_ref() }),
Err(..) => Err(value), // locked or spurious failure
}
}
@@ -126,7 +127,7 @@ impl<T> OnceCell<T> {
};
// SAFETY: just in case AtomicU8 has a drop handler
unsafe {
- ptr::drop_in_place(&mut self.state as *mut _);
+ ptr::drop_in_place(std::ptr::addr_of_mut!(self.state));
}
std::mem::forget(self);
inner