mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 03:40:23 +00:00
Added dcb::game::card::table::Header and dcb::game::card::Header for the table header and card header in the table, respectively.
Modified `dcb::game::card::Table` to use these new headers.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
// Modules
|
||||
pub mod digimon;
|
||||
pub mod digivolve;
|
||||
pub mod header;
|
||||
pub mod item;
|
||||
pub mod property;
|
||||
pub mod table;
|
||||
@@ -13,5 +14,6 @@ pub mod table;
|
||||
// Exports
|
||||
pub use digimon::Digimon;
|
||||
pub use digivolve::Digivolve;
|
||||
pub use header::CardHeader;
|
||||
pub use item::Item;
|
||||
pub use table::Table;
|
||||
|
||||
9
dcb/src/game/card/header.md
Normal file
9
dcb/src/game/card/header.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Header for each card in the table.
|
||||
|
||||
# Details
|
||||
Each header contains the id of the card, as well as it's type.
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | ---- | ------------ | --------- | ------------------------------------------------ |
|
||||
| 0x0 | 0x2 | u16 | Card id | This card's ID |
|
||||
| 0x2 | 0x1 | [`CardType`] | Card type | The card type ([Digimon], [Item] or [Digivolve]) |
|
||||
55
dcb/src/game/card/header.rs
Normal file
55
dcb/src/game/card/header.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
#![doc(include = "header.md")]
|
||||
|
||||
// Modules
|
||||
pub mod error;
|
||||
|
||||
// Exports
|
||||
pub use error::FromBytesError;
|
||||
|
||||
// Includes
|
||||
use crate::{
|
||||
game::card::property::CardType,
|
||||
util::{array_split, array_split_mut},
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
|
||||
/// Card header
|
||||
pub struct CardHeader {
|
||||
/// Card id
|
||||
pub id: u16,
|
||||
|
||||
/// Card type
|
||||
pub ty: CardType,
|
||||
}
|
||||
|
||||
|
||||
impl Bytes for CardHeader {
|
||||
type ByteArray = [u8; 0x3];
|
||||
type FromError = FromBytesError;
|
||||
type ToError = !;
|
||||
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError> {
|
||||
let bytes = array_split!(bytes,
|
||||
id: [0x2],
|
||||
ty: 0x1,
|
||||
);
|
||||
|
||||
let id = LittleEndian::read_u16(bytes.id);
|
||||
let ty = CardType::from_bytes(bytes.ty).map_err(FromBytesError::CardType)?;
|
||||
|
||||
Ok(Self { id, ty })
|
||||
}
|
||||
|
||||
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError> {
|
||||
let bytes = array_split_mut!(bytes,
|
||||
id: [0x2],
|
||||
ty: 0x1,
|
||||
);
|
||||
|
||||
LittleEndian::write_u16(bytes.id, self.id);
|
||||
self.ty.to_bytes(bytes.ty).into_ok();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
12
dcb/src/game/card/header/error.rs
Normal file
12
dcb/src/game/card/header/error.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
//! Errors
|
||||
|
||||
// Imports
|
||||
use crate::game::card::property::card_type;
|
||||
|
||||
/// Error type for [`Bytes::from_bytes`](dcb_bytes::Bytes::from_bytes)
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, thiserror::Error)]
|
||||
pub enum FromBytesError {
|
||||
/// Unable to parse card type
|
||||
#[error("Unable to parse the card type")]
|
||||
CardType(#[source] card_type::FromBytesError),
|
||||
}
|
||||
@@ -1,34 +1,23 @@
|
||||
The table of all digimon in the game
|
||||
|
||||
# Details
|
||||
At address [0x216d000](Table::START_ADDRESS) of the game file, the card table begins
|
||||
with a small header of `0xb` and then the table itself.
|
||||
The card table begins at address [0x216d000](Table::START_ADDRESS) of the game file,
|
||||
containing a header with the number of each card, and then a contiguous array of card entries.
|
||||
|
||||
# Table Layout
|
||||
The digimon table has a max size of [0x14950](Table::MAX_BYTE_SIZE), but does not
|
||||
necessary use all of this space, but it does follow this layout:
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | --------------------------------- | -------------------- | ----------------------------------------------------------------------- |
|
||||
| 0x0 | 0x4 | u32 | Magic | Always contains the string "0ACD" (= [0x44434130](Table::HEADER_MAGIC)) |
|
||||
| 0x4 | 0x2 | u16 | Number of digimon | |
|
||||
| 0x6 | 0x1 | u8 | Number of items | |
|
||||
| 0x7 | 0x1 | u8 | Number of digivolves | |
|
||||
| 0x8 | variable | [`CardEntry`](#card-entry-layout) | Card Entries | A contiguous array of [Card Entry](#card-entry-layout) |
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | --------------------------------- | ------------ | ------------------------------------------------------ |
|
||||
| 0x0 | 0x8 | u32 | Header | The [table header](TableHeader) |
|
||||
| 0x8 | variable | [`CardEntry`](#card-entry-layout) | Card Entries | A contiguous array of [Card Entry](#card-entry-layout) |
|
||||
|
||||
# Card Entry Layout
|
||||
Each card entry consists of a header of the card
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | ------------------------------------ | --------------- | -------------------------------------------- |
|
||||
| 0x0 | 0x3 | [`Card Header`](#card-header-layout) | Card Header | The card's header |
|
||||
| 0x3 | variable | | Card | Either a [Digimon], [Item] or [Digivolve] |
|
||||
| ... | 0x1 | u8 | Null terminator | A null terminator for the card (must be `0`) |
|
||||
|
||||
# Card Header Layout
|
||||
The card header determines which type of card this card entry has.
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | ---- | ------------ | --------- | ------------------------------------------------ |
|
||||
| 0x0 | 0x2 | u16 | Card id | This card's ID |
|
||||
| 0x2 | 0x1 | [`CardType`] | Card type | The card type ([Digimon], [Item] or [Digivolve]) |
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | -------------- | --------------- | -------------------------------------------- |
|
||||
| 0x0 | 0x3 | [`CardHeader`] | Card Header | The card's header |
|
||||
| 0x3 | variable | | Card | Either a [Digimon], [Item] or [Digivolve] |
|
||||
| ... | 0x1 | u8 | Null terminator | A null terminator for the card (must be `0`) |
|
||||
|
||||
@@ -2,34 +2,28 @@
|
||||
|
||||
// Modules
|
||||
pub mod error;
|
||||
pub mod header;
|
||||
|
||||
// Exports
|
||||
pub use error::{DeserializeError, SerializeError};
|
||||
pub use header::Header;
|
||||
|
||||
// Imports
|
||||
use crate::{
|
||||
game::card::{
|
||||
self,
|
||||
property::{self, CardType},
|
||||
Digimon, Digivolve, Item,
|
||||
},
|
||||
game::card::{self, property::CardType, CardHeader, Digimon, Digivolve, Item},
|
||||
io::{address::Data, GameFile},
|
||||
util::{array_split, array_split_mut},
|
||||
util::array_split_mut,
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
io::{Read, Seek, Write},
|
||||
};
|
||||
|
||||
/// The table storing all cards
|
||||
///
|
||||
/// See the [module containing](self) this struct for more details
|
||||
/// on where the table is deserialized from and it's features / restrictions.
|
||||
/// Table storing all cards.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[allow(clippy::unsafe_derive_deserialize)] // We don't have any `unsafe` methods
|
||||
#[allow(clippy::unsafe_derive_deserialize)] // False positive
|
||||
pub struct Table {
|
||||
/// All digimons in this table
|
||||
pub digimons: Vec<Digimon>,
|
||||
@@ -43,11 +37,6 @@ pub struct Table {
|
||||
|
||||
// Constants
|
||||
impl Table {
|
||||
/// Table header size
|
||||
pub const HEADER_BYTE_SIZE: usize = 0x8;
|
||||
/// The magic in the table header
|
||||
/// = "0ACD"
|
||||
pub const HEADER_MAGIC: u32 = 0x44434130;
|
||||
/// The max size of the card table
|
||||
// TODO: Check the theoretical max, which is currently thought to be `0x14ff5`
|
||||
pub const MAX_BYTE_SIZE: usize = 0x14970;
|
||||
@@ -81,26 +70,14 @@ impl Table {
|
||||
.map_err(DeserializeError::Seek)?;
|
||||
|
||||
// Read header
|
||||
let mut header_bytes = [0u8; Self::HEADER_BYTE_SIZE];
|
||||
let mut header_bytes = <Header as Bytes>::ByteArray::default();
|
||||
file.read_exact(&mut header_bytes).map_err(DeserializeError::ReadHeader)?;
|
||||
let header = array_split! {&header_bytes,
|
||||
magic: [0x4],
|
||||
|
||||
digimons_len: [0x2],
|
||||
items_len: 1,
|
||||
digivolves_len: 1,
|
||||
};
|
||||
|
||||
// Check if the magic is right
|
||||
let magic = LittleEndian::read_u32(header.magic);
|
||||
if magic != Self::HEADER_MAGIC {
|
||||
return Err(DeserializeError::HeaderMagic { magic });
|
||||
}
|
||||
let header = Header::from_bytes(&header_bytes).map_err(DeserializeError::Header)?;
|
||||
|
||||
// Then check the number of each card
|
||||
let digimon_cards: usize = LittleEndian::read_u16(header.digimons_len).into();
|
||||
let item_cards: usize = (*header.items_len).into();
|
||||
let digivolve_cards: usize = (*header.digivolves_len).into();
|
||||
let digimon_cards: usize = header.digimons_len.into();
|
||||
let item_cards: usize = header.items_len.into();
|
||||
let digivolve_cards: usize = header.digivolves_len.into();
|
||||
log::trace!("Found {digimon_cards} digimon, {item_cards} item, {digivolve_cards} digivolve cards");
|
||||
|
||||
// And calculate the number of cards
|
||||
@@ -124,43 +101,51 @@ impl Table {
|
||||
let mut digivolves = Vec::with_capacity(digivolve_cards);
|
||||
|
||||
// Read until the table is over
|
||||
for cur_id in 0..cards_len {
|
||||
for card_id in 0..cards_len {
|
||||
// Read card header bytes
|
||||
let mut card_header_bytes = [0u8; 0x3];
|
||||
file.read_exact(&mut card_header_bytes)
|
||||
.map_err(|err| DeserializeError::ReadCardHeader { id: cur_id, err })?;
|
||||
.map_err(|err| DeserializeError::ReadCardHeader { id: card_id, err })?;
|
||||
|
||||
// Read the header
|
||||
let card_id = LittleEndian::read_u16(&card_header_bytes[0x0..0x2]);
|
||||
let card_type = CardType::from_bytes(&card_header_bytes[0x2]).map_err(|err| DeserializeError::UnknownCardType { id: cur_id, err })?;
|
||||
let card_header = CardHeader::from_bytes(&card_header_bytes).map_err(|err| DeserializeError::ParseCardHeader { id: card_id, err })?;
|
||||
|
||||
log::trace!("Found #{}: {}", card_id, card_type);
|
||||
log::trace!("Found #{}: {}", card_id, card_header.ty);
|
||||
|
||||
// If the card id isn't what we expected, log warning
|
||||
if usize::from(card_id) != cur_id {
|
||||
log::warn!("Card with id {} had unexpected id {}", cur_id, card_id);
|
||||
if usize::from(card_header.id) != card_id {
|
||||
log::warn!("Card with id {} had unexpected id {}", card_id, card_header.id);
|
||||
}
|
||||
// And create / push the card
|
||||
match card_type {
|
||||
match card_header.ty {
|
||||
CardType::Digimon => {
|
||||
let mut digimon_bytes = [0; std::mem::size_of::<<Digimon as Bytes>::ByteArray>()];
|
||||
file.read_exact(&mut digimon_bytes)
|
||||
.map_err(|err| DeserializeError::ReadCard { id: cur_id, card_type, err })?;
|
||||
let digimon = Digimon::from_bytes(&digimon_bytes).map_err(|err| DeserializeError::DigimonCard { id: cur_id, err })?;
|
||||
file.read_exact(&mut digimon_bytes).map_err(|err| DeserializeError::ReadCard {
|
||||
id: card_id,
|
||||
card_type: card_header.ty,
|
||||
err,
|
||||
})?;
|
||||
let digimon = Digimon::from_bytes(&digimon_bytes).map_err(|err| DeserializeError::DigimonCard { id: card_id, err })?;
|
||||
digimons.push(digimon);
|
||||
},
|
||||
CardType::Item => {
|
||||
let mut item_bytes = [0; std::mem::size_of::<<Item as Bytes>::ByteArray>()];
|
||||
file.read_exact(&mut item_bytes)
|
||||
.map_err(|err| DeserializeError::ReadCard { id: cur_id, card_type, err })?;
|
||||
let item = Item::from_bytes(&item_bytes).map_err(|err| DeserializeError::ItemCard { id: cur_id, err })?;
|
||||
file.read_exact(&mut item_bytes).map_err(|err| DeserializeError::ReadCard {
|
||||
id: card_id,
|
||||
card_type: card_header.ty,
|
||||
err,
|
||||
})?;
|
||||
let item = Item::from_bytes(&item_bytes).map_err(|err| DeserializeError::ItemCard { id: card_id, err })?;
|
||||
items.push(item);
|
||||
},
|
||||
CardType::Digivolve => {
|
||||
let mut digivolve_bytes = [0; std::mem::size_of::<<Digivolve as Bytes>::ByteArray>()];
|
||||
file.read_exact(&mut digivolve_bytes)
|
||||
.map_err(|err| DeserializeError::ReadCard { id: cur_id, card_type, err })?;
|
||||
let digivolve = Digivolve::from_bytes(&digivolve_bytes).map_err(|err| DeserializeError::DigivolveCard { id: cur_id, err })?;
|
||||
file.read_exact(&mut digivolve_bytes).map_err(|err| DeserializeError::ReadCard {
|
||||
id: card_id,
|
||||
card_type: card_header.ty,
|
||||
err,
|
||||
})?;
|
||||
let digivolve = Digivolve::from_bytes(&digivolve_bytes).map_err(|err| DeserializeError::DigivolveCard { id: card_id, err })?;
|
||||
digivolves.push(digivolve);
|
||||
},
|
||||
}
|
||||
@@ -168,9 +153,9 @@ impl Table {
|
||||
// Skip null terminator
|
||||
let mut null_terminator = [0; 1];
|
||||
file.read_exact(&mut null_terminator)
|
||||
.map_err(|err| DeserializeError::ReadCardFooter { id: cur_id, err })?;
|
||||
.map_err(|err| DeserializeError::ReadCardFooter { id: card_id, err })?;
|
||||
if null_terminator[0] != 0 {
|
||||
log::warn!("Card with id {}'s null terminator was {} instead of 0", cur_id, null_terminator[0]);
|
||||
log::warn!("Card with id {}'s null terminator was {} instead of 0", card_id, null_terminator[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,27 +183,12 @@ impl Table {
|
||||
|
||||
// Write header
|
||||
let mut header_bytes = [0u8; 0x8];
|
||||
let header = array_split_mut!(&mut header_bytes,
|
||||
magic: [0x4],
|
||||
|
||||
digimons_len: [0x2],
|
||||
items_len: 1,
|
||||
digivolves_len: 1,
|
||||
);
|
||||
|
||||
// Set magic
|
||||
LittleEndian::write_u32(header.magic, Self::HEADER_MAGIC);
|
||||
|
||||
// Write card lens
|
||||
log::trace!("Writing {} digimon cards", self.digimons.len());
|
||||
log::trace!("Writing {} item cards", self.items.len());
|
||||
log::trace!("Writing {} digivolve cards", self.digivolves.len());
|
||||
LittleEndian::write_u16(
|
||||
header.digimons_len,
|
||||
self.digimons.len().try_into().expect("Number of digimon cards exceeded `u16`"),
|
||||
);
|
||||
*header.items_len = self.items.len().try_into().expect("Number of item cards exceeded `u8`");
|
||||
*header.digivolves_len = self.digivolves.len().try_into().expect("Number of digivolve cards exceeded `u8`");
|
||||
let header = Header {
|
||||
digimons_len: self.digimons.len().try_into().expect("Number of digimon cards exceeded `u16`"),
|
||||
items_len: self.items.len().try_into().expect("Number of item cards exceeded `u8`"),
|
||||
digivolves_len: self.digivolves.len().try_into().expect("Number of digivolve cards exceeded `u8`"),
|
||||
};
|
||||
header.to_bytes(&mut header_bytes).into_ok();
|
||||
|
||||
// And write the header
|
||||
file.write_all(&header_bytes).map_err(SerializeError::WriteHeader)?;
|
||||
@@ -233,15 +203,16 @@ impl Table {
|
||||
// Card bytes
|
||||
let mut card_bytes = [0; 0x3 + CardType::$card_type.byte_size() + 0x1];
|
||||
let bytes = array_split_mut!(&mut card_bytes,
|
||||
header_id : [0x2],
|
||||
header_type: 1,
|
||||
header : [0x3],
|
||||
card : [CardType::$card_type.byte_size()],
|
||||
footer : 1,
|
||||
);
|
||||
|
||||
// Write the header
|
||||
LittleEndian::write_u16(bytes.header_id, cur_id.try_into().expect("Card ID exceeded `u16`"));
|
||||
CardType::$card_type.to_bytes(bytes.header_type)?;
|
||||
let card_header = CardHeader {
|
||||
id: cur_id.try_into().expect("Card id didn't fit into a `u16`"),
|
||||
ty: CardType::$card_type,
|
||||
};
|
||||
card_header.to_bytes(bytes.header).into_ok();
|
||||
|
||||
// Write the card
|
||||
#[allow(unreachable_code)] // FIXME: Remove this
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Errors
|
||||
|
||||
// Imports
|
||||
use super::{card, property, CardType, Table};
|
||||
use super::{card, header, CardType, Table};
|
||||
|
||||
/// Error type for [`Table::deserialize`]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
@@ -14,12 +14,9 @@ pub enum DeserializeError {
|
||||
#[error("Unable to read table header")]
|
||||
ReadHeader(#[source] std::io::Error),
|
||||
|
||||
/// The magic of the table was wrong
|
||||
#[error("Found wrong table header magic (expected {:#x}, found {:#x})", Table::HEADER_MAGIC, magic)]
|
||||
HeaderMagic {
|
||||
/// Magic we found
|
||||
magic: u32,
|
||||
},
|
||||
/// Unable to parse table header
|
||||
#[error("Unable to parse table header")]
|
||||
Header(#[source] header::FromBytesError),
|
||||
|
||||
/// There were too many cards
|
||||
#[error(
|
||||
@@ -51,15 +48,15 @@ pub enum DeserializeError {
|
||||
err: std::io::Error,
|
||||
},
|
||||
|
||||
/// An unknown card type was found
|
||||
#[error("Unknown card type for card id {}", id)]
|
||||
UnknownCardType {
|
||||
/// Unable to parse a card header
|
||||
#[error("Unable to parse a card header for card id {id}")]
|
||||
ParseCardHeader {
|
||||
/// Id of card
|
||||
id: usize,
|
||||
|
||||
/// Underlying error
|
||||
#[source]
|
||||
err: property::card_type::FromBytesError,
|
||||
err: card::header::FromBytesError,
|
||||
},
|
||||
|
||||
/// Unable to read a card
|
||||
|
||||
15
dcb/src/game/card/table/header.md
Normal file
15
dcb/src/game/card/table/header.md
Normal file
@@ -0,0 +1,15 @@
|
||||
Header for the digimon table.
|
||||
|
||||
# Details
|
||||
The header contains a magic number to identify the table, as well as the number of each card
|
||||
available.
|
||||
|
||||
The number of digimons is measured with a `u16`, but the items and digivolves are only measured using
|
||||
a `u8`, meaning they have a limit of `256`.
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | ---- | ---- | -------------------- | ---------------------------------------------------------- |
|
||||
| 0x0 | 0x4 | u32 | Magic | Always contains the string ["0ACD"]((Table::HEADER_MAGIC)) |
|
||||
| 0x4 | 0x2 | u16 | Number of digimon | |
|
||||
| 0x6 | 0x1 | u8 | Number of items | |
|
||||
| 0x7 | 0x1 | u8 | Number of digivolves | |
|
||||
77
dcb/src/game/card/table/header.rs
Normal file
77
dcb/src/game/card/table/header.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
#![doc(include = "header.md")]
|
||||
|
||||
// Modules
|
||||
pub mod error;
|
||||
|
||||
// Exports
|
||||
pub use error::FromBytesError;
|
||||
|
||||
// Imports
|
||||
use crate::util::{array_split, array_split_mut};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
|
||||
/// The header
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
pub struct Header {
|
||||
/// Number of digimon
|
||||
pub digimons_len: u16,
|
||||
|
||||
/// Number of items
|
||||
pub items_len: u8,
|
||||
|
||||
/// Number of digivolves
|
||||
pub digivolves_len: u8,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
/// Magic of this header.
|
||||
/// = "0ACD"
|
||||
pub const MAGIC: [u8; 4] = *b"0ACD";
|
||||
}
|
||||
|
||||
impl Bytes for Header {
|
||||
type ByteArray = [u8; 0x8];
|
||||
type FromError = FromBytesError;
|
||||
type ToError = !;
|
||||
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError> {
|
||||
let bytes = array_split!(bytes,
|
||||
magic: [0x4],
|
||||
digimons_len: [0x2],
|
||||
items_len: 1,
|
||||
digivolves_len: 1,
|
||||
);
|
||||
|
||||
if *bytes.magic != Self::MAGIC {
|
||||
return Err(FromBytesError::Magic { magic: *bytes.magic });
|
||||
}
|
||||
|
||||
let digimons_len = LittleEndian::read_u16(bytes.digimons_len);
|
||||
let items_len = *bytes.items_len;
|
||||
let digivolves_len = *bytes.digivolves_len;
|
||||
|
||||
Ok(Self {
|
||||
digimons_len,
|
||||
items_len,
|
||||
digivolves_len,
|
||||
})
|
||||
}
|
||||
|
||||
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError> {
|
||||
let bytes = array_split_mut!(bytes,
|
||||
magic: [0x4],
|
||||
digimons_len: [0x2],
|
||||
items_len: 1,
|
||||
digivolves_len: 1,
|
||||
);
|
||||
|
||||
*bytes.magic = Self::MAGIC;
|
||||
LittleEndian::write_u16(bytes.digimons_len, self.digimons_len);
|
||||
*bytes.items_len = self.items_len;
|
||||
*bytes.digivolves_len = self.digivolves_len;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
15
dcb/src/game/card/table/header/error.rs
Normal file
15
dcb/src/game/card/table/header/error.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
//! Errors
|
||||
|
||||
// Imports
|
||||
use super::Header;
|
||||
|
||||
/// Error type for [`Bytes::from_bytes`](dcb_bytes::Bytes::from_bytes)
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, thiserror::Error)]
|
||||
pub enum FromBytesError {
|
||||
/// Magic
|
||||
#[error("Magic did not match (found {magic:#x?}, expected {:#x?})", Header::MAGIC)]
|
||||
Magic {
|
||||
/// Magic that was found
|
||||
magic: [u8; 4],
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user