mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-11 12:41:48 +00:00
Moved util from game module to crate level to add functions more global, outside of game.
Removed all `as` conversions lints and fixed code using them.
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
#![doc(include = "digimon.md")]
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
card::property::{self, ArrowColor, CrossMoveEffect, Effect, EffectCondition, Level, Move, Speciality},
|
||||
use crate::{
|
||||
game::{
|
||||
card::property::{self, ArrowColor, CrossMoveEffect, Effect, EffectCondition, Level, Move, Speciality},
|
||||
Bytes,
|
||||
},
|
||||
util::{
|
||||
array_split, array_split_mut,
|
||||
null_ascii_string::{self, NullAsciiString},
|
||||
},
|
||||
Bytes,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#![doc(include = "digivolve.md")]
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
use crate::{
|
||||
game::Bytes,
|
||||
util::{
|
||||
array_split, array_split_mut,
|
||||
null_ascii_string::{self, NullAsciiString},
|
||||
},
|
||||
Bytes,
|
||||
};
|
||||
|
||||
/// A digivolve card
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#![doc(include = "item.md")]
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
card::property::{self, ArrowColor, Effect, EffectCondition},
|
||||
use crate::{
|
||||
game::{
|
||||
card::property::{self, ArrowColor, Effect, EffectCondition},
|
||||
Bytes,
|
||||
},
|
||||
util::{
|
||||
array_split, array_split_mut,
|
||||
null_ascii_string::{self, NullAsciiString},
|
||||
},
|
||||
Bytes,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#![doc(include = "effect.md")]
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
card::property::{self, AttackType, DigimonProperty, EffectOperation, PlayerType, Slot},
|
||||
use crate::{
|
||||
game::{
|
||||
card::property::{self, AttackType, DigimonProperty, EffectOperation, PlayerType, Slot},
|
||||
Bytes,
|
||||
},
|
||||
util::{array_split, array_split_mut},
|
||||
Bytes,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#![doc(include = "effect_condition.md")]
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
card::property::{self, DigimonProperty, EffectConditionOperation},
|
||||
use crate::{
|
||||
game::{
|
||||
card::property::{self, DigimonProperty, EffectConditionOperation},
|
||||
Bytes,
|
||||
},
|
||||
util::{array_split, array_split_mut},
|
||||
Bytes,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
mod test;
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
use crate::{
|
||||
game::{Bytes, Validatable, Validation},
|
||||
util::{
|
||||
array_split, array_split_mut,
|
||||
null_ascii_string::{self, NullAsciiString},
|
||||
},
|
||||
Bytes, Validatable, Validation,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -8,13 +8,16 @@ use crate::{
|
||||
property::{self, CardType},
|
||||
Digimon, Digivolve, Item,
|
||||
},
|
||||
util::array_split_mut,
|
||||
Bytes,
|
||||
},
|
||||
io::{address::Data, GameFile},
|
||||
util::array_split_mut,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use std::io::{Read, Seek, Write};
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
io::{Read, Seek, Write},
|
||||
};
|
||||
|
||||
/// The table storing all cards
|
||||
#[derive(Debug)]
|
||||
@@ -291,9 +294,9 @@ impl Table {
|
||||
}
|
||||
|
||||
// Then check the number of each card
|
||||
let digimon_cards = LittleEndian::read_u16(&header_bytes[0x4..0x6]) as usize;
|
||||
let item_cards = header_bytes[0x6] as usize;
|
||||
let digivolve_cards = header_bytes[0x7] as usize;
|
||||
let digimon_cards: usize = LittleEndian::read_u16(&header_bytes[0x4..0x6]).into();
|
||||
let item_cards: usize = header_bytes[0x6].into();
|
||||
let digivolve_cards: usize = header_bytes[0x7].into();
|
||||
log::debug!("[Table Header] Found {} digimon cards", digimon_cards);
|
||||
log::debug!("[Table Header] Found {} item cards", item_cards);
|
||||
log::debug!("[Table Header] Found {} digivolve cards", digivolve_cards);
|
||||
@@ -409,13 +412,15 @@ impl Table {
|
||||
LittleEndian::write_u32(bytes.magic, Self::HEADER_MAGIC);
|
||||
|
||||
// Write card lens
|
||||
use std::convert::TryInto;
|
||||
log::debug!("[Table Header] Writing {} digimon cards", self.digimons.len());
|
||||
log::debug!("[Table Header] Writing {} item cards", self.items.len());
|
||||
log::debug!("[Table Header] Writing {} digivolve cards", self.digivolves.len());
|
||||
LittleEndian::write_u16(bytes.digimons_len, self.digimons.len().try_into().expect("Too many digimons"));
|
||||
*bytes.items_len = self.items.len().try_into().expect("Too many items");
|
||||
*bytes.digivolves_len = self.digivolves.len().try_into().expect("Too many digivolves");
|
||||
LittleEndian::write_u16(
|
||||
bytes.digimons_len,
|
||||
self.digimons.len().try_into().expect("Number of digimon cards exceeded `u16`"),
|
||||
);
|
||||
*bytes.items_len = self.items.len().try_into().expect("Number of item cards exceeded `u8`");
|
||||
*bytes.digivolves_len = self.digivolves.len().try_into().expect("Number of digivolve cards exceeded `u8`");
|
||||
}
|
||||
|
||||
file.write_all(&header_bytes).map_err(SerializeError::WriteHeader)?;
|
||||
@@ -435,7 +440,7 @@ impl Table {
|
||||
);
|
||||
|
||||
// Write the header
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id as u16);
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id.try_into().expect("Card ID exceeded `u16`"));
|
||||
CardType::Digimon.to_bytes(bytes.header_type)?;
|
||||
|
||||
// Write the digimon
|
||||
@@ -464,7 +469,7 @@ impl Table {
|
||||
);
|
||||
|
||||
// Write the header
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id as u16);
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id.try_into().expect("Card ID exceeded `u16`"));
|
||||
CardType::Item.to_bytes(bytes.header_type)?;
|
||||
|
||||
// Write the item
|
||||
@@ -492,7 +497,7 @@ impl Table {
|
||||
);
|
||||
|
||||
// Write the header
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id as u16);
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id.try_into().expect("Card ID exceeded `u16`"));
|
||||
CardType::Digivolve.to_bytes(bytes.header_type)?;
|
||||
|
||||
// Write the digivolve
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//! Decks
|
||||
|
||||
// Imports
|
||||
use crate::game::{
|
||||
use crate::{
|
||||
game::Bytes,
|
||||
util::{
|
||||
array_split, array_split_mut,
|
||||
null_ascii_string::{self, NullAsciiString},
|
||||
},
|
||||
Bytes,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
//! Utility macros and functions
|
||||
//!
|
||||
//! This modules is used for miscellaneous macros, functions that have
|
||||
//! not been moved to a more permanent location.
|
||||
//!
|
||||
//! All items in this module will eventually be deprecated and moved
|
||||
//! somewhere else, but this change might take some time.
|
||||
|
||||
// Modules
|
||||
pub mod array_split;
|
||||
pub mod null_ascii_string;
|
||||
|
||||
// Exports
|
||||
pub use array_split::{array_split, array_split_mut};
|
||||
@@ -1,109 +0,0 @@
|
||||
//! Array splitters
|
||||
|
||||
/// Splits an array into various members
|
||||
pub macro array_split {
|
||||
(
|
||||
$arr:expr,
|
||||
$(
|
||||
$name:ident :
|
||||
|
||||
$( [$arr_size:expr] )?
|
||||
$( $val_size:literal )?
|
||||
|
||||
),* $(,)?
|
||||
) => {{
|
||||
#![allow(
|
||||
clippy::used_underscore_binding,
|
||||
clippy::ptr_offset_with_cast,
|
||||
clippy::indexing_slicing,
|
||||
)]
|
||||
|
||||
// Struct holding all fields
|
||||
struct Fields<'a, T> {
|
||||
$(
|
||||
$name:
|
||||
|
||||
$( &'a [T; $arr_size], )?
|
||||
$( &'a T, #[cfg(invalid)] __field: [u8; $val_size], )?
|
||||
)*
|
||||
}
|
||||
|
||||
// Get everything from `array_refs`
|
||||
let (
|
||||
$(
|
||||
$name
|
||||
),*
|
||||
) = ::arrayref::array_refs!(
|
||||
$arr,
|
||||
$(
|
||||
$( $arr_size )?
|
||||
$( $val_size )?
|
||||
),*
|
||||
);
|
||||
|
||||
// And return the fields
|
||||
Fields {
|
||||
$(
|
||||
$name
|
||||
$( : &( $name[$val_size - $val_size] ) )?
|
||||
,
|
||||
)*
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
/// Splits an array into various members mutably
|
||||
#[allow(clippy::module_name_repetitions)] // `_mut` version should be in the same module
|
||||
pub macro array_split_mut {
|
||||
(
|
||||
$arr:expr,
|
||||
$(
|
||||
$name:ident :
|
||||
|
||||
$( [$arr_size:expr] )?
|
||||
$( $val_size:literal )?
|
||||
|
||||
),* $(,)?
|
||||
) => {{
|
||||
#![allow(
|
||||
clippy::used_underscore_binding,
|
||||
clippy::ptr_offset_with_cast,
|
||||
clippy::indexing_slicing,
|
||||
)]
|
||||
|
||||
// Struct holding all fields
|
||||
struct Fields<'a, T> {
|
||||
$(
|
||||
$name:
|
||||
|
||||
$( &'a mut [T; $arr_size], )?
|
||||
// Note: This `cfg` is simply done so that `__field` never appears.
|
||||
// The `__field` serves to identify when this part should be written.
|
||||
$( &'a mut T, #[cfg(invalid)] __field: [u8; $val_size], )?
|
||||
)*
|
||||
}
|
||||
|
||||
// Get everything from `array_refs`
|
||||
let (
|
||||
$(
|
||||
$name
|
||||
),*
|
||||
) = ::arrayref::mut_array_refs!(
|
||||
$arr,
|
||||
$(
|
||||
$( $arr_size )?
|
||||
$( $val_size )?
|
||||
),*
|
||||
);
|
||||
|
||||
// And return the fields
|
||||
Fields {
|
||||
$(
|
||||
$name
|
||||
// Note: This serves to turn a `&mut [u8; 1]` into a `&mut u8`.
|
||||
$( : &mut ( $name[$val_size - $val_size] ) )?
|
||||
,
|
||||
)*
|
||||
}
|
||||
}}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
//! Null-terminated ascii string helpers
|
||||
|
||||
// Modules
|
||||
pub mod error;
|
||||
|
||||
// Exports
|
||||
pub use error::{ReadError, WriteError};
|
||||
|
||||
/// Trait for reading null terminated ascii strings from a buffer
|
||||
pub trait NullAsciiString {
|
||||
/// Reads a null terminated ascii string from this buffer and returns it
|
||||
fn read_string(&self) -> Result<&ascii::AsciiStr, ReadError>;
|
||||
|
||||
/// Writes a null terminated ascii string to this buffer and returns it
|
||||
fn write_string(&mut self, s: &ascii::AsciiStr) -> Result<&Self, WriteError>;
|
||||
}
|
||||
|
||||
impl NullAsciiString for [u8] {
|
||||
fn read_string(&self) -> Result<&ascii::AsciiStr, ReadError> {
|
||||
// Find the first null and trim the buffer until it
|
||||
let buf = match self.iter().position(|&b| b == b'\0') {
|
||||
Some(idx) => &self[0..idx],
|
||||
None => return Err(ReadError::NoNull),
|
||||
};
|
||||
|
||||
// Then convert it from Ascii
|
||||
ascii::AsciiStr::from_ascii(buf).map_err(ReadError::NotAscii)
|
||||
}
|
||||
|
||||
fn write_string(&mut self, input: &ascii::AsciiStr) -> Result<&Self, WriteError> {
|
||||
// If the input string doesn't fit into the buffer (excluding the null byte), return Err
|
||||
if input.len() >= self.len() {
|
||||
return Err(WriteError::TooLarge {
|
||||
input_len: input.len(),
|
||||
buffer_len: self.len(),
|
||||
});
|
||||
}
|
||||
|
||||
// Else copy everything over and set the last byte to null
|
||||
// Note: We leave all other bytes as they are, no need to set them to 0
|
||||
self[0..input.len()].copy_from_slice(input.as_bytes());
|
||||
self[input.len()] = 0;
|
||||
|
||||
// And return Ok with the buffer
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
//! Errors
|
||||
|
||||
/// Error type for [`read`](super::read)
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, thiserror::Error)]
|
||||
pub enum ReadError {
|
||||
/// No null was found in the string
|
||||
#[error("No null was found on the buffer")]
|
||||
NoNull,
|
||||
|
||||
/// The string was not ascii
|
||||
#[error("The buffer did not contain valid Ascii")]
|
||||
NotAscii(#[source] ascii::AsAsciiStrError),
|
||||
}
|
||||
|
||||
/// Error type for [`write`](super::read)
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, thiserror::Error)]
|
||||
#[allow(clippy::missing_docs_in_private_items)]
|
||||
pub enum WriteError {
|
||||
/// The input string was too large
|
||||
#[error("Input string was too large for buffer. ({}+1 / {})", input_len, buffer_len)]
|
||||
TooLarge { input_len: usize, buffer_len: usize },
|
||||
}
|
||||
Reference in New Issue
Block a user