mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 03:40:23 +00:00
Added various rustfmt configurations.
Revised documentation of the library and lint opt-out reasons. Moved some module documentation to it's own file due to overflowing the line limit. Fixed several spelling errors.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//! Interface for converting various structures to and from bytes
|
||||
|
||||
/// Convertions to and from bytes for the game file
|
||||
/// Conversions to and from bytes for the game file
|
||||
pub trait Bytes
|
||||
where
|
||||
Self: Sized,
|
||||
|
||||
28
src/game/card/digimon.md
Normal file
28
src/game/card/digimon.md
Normal file
@@ -0,0 +1,28 @@
|
||||
A digimon card
|
||||
|
||||
This module contains the [`Digimon`] struct, which describes a digimon card.
|
||||
|
||||
# Layout
|
||||
The digimon card has a size of `0x138` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | ---------------------- | ----------------------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x2 | `u16` | Unknown | `unknown_15` | |
|
||||
| 0x17 | 0x1 | `u8` | Speciality & Level | `speciality level` | The bottom nibble of this byte is the level, while the top nibble is the speciality |
|
||||
| 0x18 | 0x1 | `u8` | DP | `dp_cost` | |
|
||||
| 0x19 | 0x1 | `u8` | +P | `dp_give` | |
|
||||
| 0x1a | 0x1 | `u8` | Unknown | `unknown_1a` | Is `0` for all digimon |
|
||||
| 0x1b | 0x2 | `u16` | Health | `hp` | |
|
||||
| 0x1d | 0x1c | [`Move`] | Circle Move | `move_circle` | |
|
||||
| 0x39 | 0x1c | [`Move`] | Triangle move | `move_triangle` | |
|
||||
| 0x55 | 0x1c | [`Move`] | Cross move | `move_cross` | |
|
||||
| 0x71 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
| 0x91 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
| 0xb1 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
| 0xc1 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
| 0xd1 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
| 0xe1 | 0x1 | [`CrossMoveEffect`] | Cross move effect | `cross_move_effect` | |
|
||||
| 0xe2 | 0x1 | `u8` | Unknown | `unknown_e2` | |
|
||||
| 0xe3 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
| 0xe4 | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,31 +1,4 @@
|
||||
//! A digimon card
|
||||
//!
|
||||
//! This module contains the [`Digimon`] struct, which describes a digimon card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The digimon card has a size of `0x138` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|-------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x2 | `u16` | Unknown | `unknown_15` | |
|
||||
//! | 0x17 | 0x1 | `u8` | Speciality & Level | `speciality level` | The bottom nibble of this byte is the level, while the top nibble is the speciality |
|
||||
//! | 0x18 | 0x1 | `u8` | DP | `dp_cost` | |
|
||||
//! | 0x19 | 0x1 | `u8` | +P | `dp_give` | |
|
||||
//! | 0x1a | 0x1 | `u8` | Unknown | `unknown_1a` | Is `0` for all digimon |
|
||||
//! | 0x1b | 0x2 | `u16` | Health | `hp` | |
|
||||
//! | 0x1d | 0x1c | [`Move`] | Circle Move | `move_circle` | |
|
||||
//! | 0x39 | 0x1c | [`Move`] | Triangle move | `move_triangle` | |
|
||||
//! | 0x55 | 0x1c | [`Move`] | Cross move | `move_cross` | |
|
||||
//! | 0x71 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
//! | 0x91 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
//! | 0xb1 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
//! | 0xc1 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
//! | 0xd1 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
//! | 0xe1 | 0x1 | [`CrossMoveEffect`] | Cross move effect | `cross_move_effect` | |
|
||||
//! | 0xe2 | 0x1 | `u8` | Unknown | `unknown_e2` | |
|
||||
//! | 0xe3 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
//! | 0xe4 | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "digimon.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -275,9 +248,9 @@ impl Bytes for Digimon {
|
||||
hp: LittleEndian::read_u16(bytes.hp),
|
||||
|
||||
// Moves
|
||||
move_circle: Move::from_bytes(bytes.move_circle).map_err(FromBytesError::MoveCircle)?,
|
||||
move_circle: Move::from_bytes(bytes.move_circle).map_err(FromBytesError::MoveCircle)?,
|
||||
move_triangle: Move::from_bytes(bytes.move_triangle).map_err(FromBytesError::MoveTriangle)?,
|
||||
move_cross: Move::from_bytes(bytes.move_cross).map_err(FromBytesError::MoveCross)?,
|
||||
move_cross: Move::from_bytes(bytes.move_cross).map_err(FromBytesError::MoveCross)?,
|
||||
|
||||
// Effects
|
||||
effect_conditions: [
|
||||
|
||||
12
src/game/card/digivolve.md
Normal file
12
src/game/card/digivolve.md
Normal file
@@ -0,0 +1,12 @@
|
||||
A digivolve card
|
||||
|
||||
This module contains the [`Digivolve`] struct, which describes a digivolve card.
|
||||
|
||||
# Layout
|
||||
The digivolve card has a size of `0x6c` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | -------------------- | ------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x3 | `[u8; 3]` | Unknown | `unknown_15` | Probably contains the card effect |
|
||||
| 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,15 +1,4 @@
|
||||
//! A digivolve card
|
||||
//!
|
||||
//! This module contains the [`Digivolve`] struct, which describes a digivolve card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The digivolve card has a size of `0x6c` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|---------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x3 | `[u8; 3]` | Unknown | `unknown_15` | Probably contains the card effect |
|
||||
//! | 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "digivolve.md")]
|
||||
|
||||
// Crate
|
||||
use crate::game::{util, Bytes};
|
||||
|
||||
18
src/game/card/item.md
Normal file
18
src/game/card/item.md
Normal file
@@ -0,0 +1,18 @@
|
||||
An item card
|
||||
|
||||
This module contains the [`Item`] struct, which describes an item card.
|
||||
|
||||
# Layout
|
||||
The item card has a size of `0xde` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | ---------------------- | ------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x4 | `u32` | Unknown | `unknown_15` | |
|
||||
| 0x19 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
| 0x39 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
| 0x59 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
| 0x69 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
| 0x79 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
| 0x89 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
| 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,21 +1,4 @@
|
||||
//! An item card
|
||||
//!
|
||||
//! This module contains the [`Item`] struct, which describes an item card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The item card has a size of `0xde` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|-------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x4 | `u32` | Unknown | `unknown_15` | |
|
||||
//! | 0x19 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
//! | 0x39 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
//! | 0x59 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
//! | 0x69 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
//! | 0x79 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
//! | 0x89 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
//! | 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "item.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
@@ -27,7 +27,7 @@ macro_rules! generate_enum_property_mod
|
||||
// Note: Must have no data
|
||||
$enum_variant_name:ident
|
||||
|
||||
// `Display` convertion name
|
||||
// `Display` conversion name
|
||||
($enum_variant_rename:literal)
|
||||
|
||||
=>
|
||||
@@ -121,7 +121,7 @@ macro_rules! generate_enum_property_mod
|
||||
/// Implements [`Bytes`](crate::game::Bytes) for `Option<E>` where `E`
|
||||
/// is the first argument of this macro and an enum.
|
||||
///
|
||||
/// This is done by suppling a sentinel value which is read/written as `None`.
|
||||
/// This is done by supplying a sentinel value which is read/written as `None`.
|
||||
macro generate_enum_property_option {
|
||||
(
|
||||
$( $enum_name:ty => $sentinel_value:literal ),* $(,)?
|
||||
|
||||
12
src/game/card/property/effect.md
Normal file
12
src/game/card/property/effect.md
Normal file
@@ -0,0 +1,12 @@
|
||||
A digimon's support effect
|
||||
|
||||
This module contains the [`Effect`] struct, which describes a support effect.
|
||||
|
||||
# Layout
|
||||
Each support effect has a size of `0x10` bytes, and it's general layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------ | ----------- | -------- | ------------------------------------------------------ |
|
||||
| 0x0 | 0x1 | `bool` | Exists | N/A | If `0`, the effect does not exist |
|
||||
| 0x1 | 0x1 | N/A | Effect Type | N/A | Determines which [`Effect`] variant is used. |
|
||||
| 0x2 | 0xe | N/A | Arguments | N/A | The arguments used for the current [`Effect`] variant. |
|
||||
@@ -1,15 +1,4 @@
|
||||
//! A digimon's support effect
|
||||
//!
|
||||
//! This module contains the [`Effect`] struct, which describes a support effect.
|
||||
//!
|
||||
//! # Layout
|
||||
//! Each support effect has a size of `0x10` bytes, and it's general layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|----------------------|---------------------------|------------------------|--------------------------------------------------------|
|
||||
//! | 0x0 | 0x1 | `bool` | Exists | N/A | If `0`, the effect does not exist |
|
||||
//! | 0x1 | 0x1 | N/A | Effect Type | N/A | Determines which [`Effect`] variant is used. |
|
||||
//! | 0x2 | 0xe | N/A | Arguments | N/A | The arguments used for the current [`Effect`] variant. |
|
||||
#![doc(include = "effect.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -23,13 +12,13 @@ use crate::game::{
|
||||
/// A digimon's support effects
|
||||
///
|
||||
/// As this type is wildly volatile in which arguments it uses and from where,
|
||||
/// it is an `enum` with struct variants instead of a struct. This simplifices argument
|
||||
/// it is an `enum` with struct variants instead of a struct. This simplifies argument
|
||||
/// verification and, from a language perspective, makes more sense as an implementation.
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
// TODO: Move this `allow` to the variant once clippy allows
|
||||
#[allow(clippy::pub_enum_variant_names)] // `Effect` on `VoidOpponentSupportEffect` isn't refering to the enum
|
||||
#[allow(clippy::pub_enum_variant_names)] // `Effect` on `VoidOpponentSupportEffect` isn't referring to the enum
|
||||
pub enum Effect {
|
||||
/// Changes a property of either digimon
|
||||
///
|
||||
@@ -75,10 +64,9 @@ pub enum Effect {
|
||||
/// `<temp slot> = <A> + (<B> <op> <C>)`
|
||||
#[serde(rename = "Set temp slot")]
|
||||
SetTempSlot {
|
||||
a: Option<DigimonProperty>,
|
||||
b: Option<DigimonProperty>,
|
||||
c: Option<DigimonProperty>,
|
||||
|
||||
a: Option<DigimonProperty>,
|
||||
b: Option<DigimonProperty>,
|
||||
c: Option<DigimonProperty>,
|
||||
op: EffectOperation,
|
||||
},
|
||||
|
||||
@@ -93,11 +81,10 @@ pub enum Effect {
|
||||
/// - `Dp` -> `Offline`
|
||||
#[serde(rename = "Move cards")]
|
||||
MoveCards {
|
||||
player: PlayerType,
|
||||
source: Slot,
|
||||
player: PlayerType,
|
||||
source: Slot,
|
||||
destination: Slot,
|
||||
|
||||
count: u16,
|
||||
count: u16,
|
||||
},
|
||||
|
||||
/// Shuffles a player's online deck
|
||||
|
||||
19
src/game/card/property/effect_condition.md
Normal file
19
src/game/card/property/effect_condition.md
Normal file
@@ -0,0 +1,19 @@
|
||||
A digimon's effect condition
|
||||
|
||||
This module contains the [`EffectCondition`] struct, which describes a condition for an effect.
|
||||
|
||||
# Layout
|
||||
Each support condition has a size of `0x20` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ---------------------------- | ----------------- | -------------- | ---------------------------------------------------------------------------------- |
|
||||
| 0x0 | 0x1 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
|
||||
| 0x1 | 0x1 | `u8` | | `unknown_1` | Always zero |
|
||||
| 0x2 | 0x1 | [`DigimonProperty`] | Property compare | `property_cmp` | The property to compare to for the condition (or 0 if the condition doesn't exist) |
|
||||
| 0x3 | 0x5 | `[u8; 0x5]` | | `unknown_3` | Unknown |
|
||||
| 0x8 | 0x1 | `DigimonProperty` | Property argument | `arg_property` | Property argument for the comparison |
|
||||
| 0x9 | 0xb | `[u8; 0xb]` | | `unknown_9` | Unknown |
|
||||
| 0x14 | 0x2 | `u16` | Number argument | `arg_num` | Number argument for the comparison |
|
||||
| 0x16 | 0x4 | `[u8; 0x4]` | | `unknown_16` | Unknown |
|
||||
| 0x1a | 0x1 | [`EffectConditionOperation`] | Operation | `operation` | Operation to use for the comparison |
|
||||
| 0x1b | 0x5 | `[u8; 0x5]` | | `unknown_1b` | Unknown |
|
||||
@@ -1,22 +1,4 @@
|
||||
//! A digimon's effect condition
|
||||
//!
|
||||
//! This module contains the [`EffectCondition`] struct, which describes a condition for an effect.
|
||||
//!
|
||||
//! # Layout
|
||||
//! Each support condition has a size of `0x20` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|------------------------------|---------------------------|--------------- |------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x1 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
|
||||
//! | 0x1 | 0x1 | `u8` | | `unknown_1` | Always zero |
|
||||
//! | 0x2 | 0x1 | [`DigimonProperty`] | Property compare | `property_cmp` | The property to compare to for the condition (or 0 if the condition doesn't exist) |
|
||||
//! | 0x3 | 0x5 | `[u8; 0x5]` | | `unknown_3` | Unknown |
|
||||
//! | 0x8 | 0x1 | `DigimonProperty` | Property argument | `arg_property` | Property argument for the comparation |
|
||||
//! | 0x9 | 0xb | `[u8; 0xb]` | | `unknown_9` | Unknown |
|
||||
//! | 0x14 | 0x2 | `u16` | Number argument | `arg_num` | Number argument for the comparation |
|
||||
//! | 0x16 | 0x4 | `[u8; 0x4]` | | `unknown_16` | Unknown |
|
||||
//! | 0x1a | 0x1 | [`EffectConditionOperation`] | Operation | `operation` | Operation to use for the comparation |
|
||||
//! | 0x1b | 0x5 | `[u8; 0x5]` | | `unknown_1b` | Unknown |
|
||||
#![doc(include = "effect_condition.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -47,9 +29,9 @@ pub struct EffectCondition {
|
||||
operation: EffectConditionOperation,
|
||||
|
||||
// Unknown
|
||||
unknown_1: u8,
|
||||
unknown_3: [u8; 0x5],
|
||||
unknown_9: [u8; 0xb],
|
||||
unknown_1: u8,
|
||||
unknown_3: [u8; 0x5],
|
||||
unknown_9: [u8; 0xb],
|
||||
unknown_16: [u8; 0x4],
|
||||
unknown_1b: [u8; 0x5],
|
||||
}
|
||||
@@ -91,7 +73,7 @@ impl Bytes for EffectCondition {
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
misfire: (*bytes.misfire != 0),
|
||||
misfire: (*bytes.misfire != 0),
|
||||
property_cmp: DigimonProperty::from_bytes(bytes.property_cmp).map_err(FromBytesError::Condition)?,
|
||||
|
||||
arg_property: Option::<DigimonProperty>::from_bytes(bytes.arg_property).map_err(FromBytesError::PropertyArgument)?,
|
||||
@@ -100,9 +82,9 @@ impl Bytes for EffectCondition {
|
||||
|
||||
operation: EffectConditionOperation::from_bytes(bytes.operation).map_err(FromBytesError::Operation)?,
|
||||
|
||||
unknown_1: *bytes.unknown_1,
|
||||
unknown_3: *bytes.unknown_3,
|
||||
unknown_9: *bytes.unknown_9,
|
||||
unknown_1: *bytes.unknown_1,
|
||||
unknown_3: *bytes.unknown_3,
|
||||
unknown_9: *bytes.unknown_9,
|
||||
unknown_16: *bytes.unknown_16,
|
||||
unknown_1b: *bytes.unknown_1b,
|
||||
})
|
||||
@@ -151,7 +133,7 @@ impl Bytes for Option<EffectCondition> {
|
||||
type ToError = <EffectCondition as crate::game::Bytes>::ToError;
|
||||
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError> {
|
||||
// If we have no property comparation, return None
|
||||
// If we have no property comparison, return None
|
||||
if bytes[0x2] == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ impl Bytes for Move {
|
||||
|
||||
// Return the move
|
||||
Ok(Self {
|
||||
name: util::read_null_ascii_string(bytes.name).map_err(FromBytesError::Name)?.to_ascii_string(),
|
||||
power: LittleEndian::read_u16(bytes.power),
|
||||
name: util::read_null_ascii_string(bytes.name).map_err(FromBytesError::Name)?.to_ascii_string(),
|
||||
power: LittleEndian::read_u16(bytes.power),
|
||||
unknown: LittleEndian::read_u32(bytes.unknown),
|
||||
})
|
||||
}
|
||||
|
||||
34
src/game/card/table.md
Normal file
34
src/game/card/table.md
Normal file
@@ -0,0 +1,34 @@
|
||||
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.
|
||||
|
||||
# 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 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]) |
|
||||
@@ -1,42 +1,4 @@
|
||||
//! 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.
|
||||
//!
|
||||
//! # 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 Entries | A contigous 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]) |
|
||||
|
||||
// Lints
|
||||
// False positive, we don't use any `unsafe` in impls
|
||||
// TODO: Remove this lint once it no longer triggers.
|
||||
#![allow(clippy::unsafe_derive_deserialize)]
|
||||
#![doc(include = "table.md")]
|
||||
|
||||
// Std
|
||||
use std::io::{Read, Seek, Write};
|
||||
@@ -121,15 +83,15 @@ pub enum DeserializeError {
|
||||
Table::MAX_BYTE_SIZE
|
||||
)]
|
||||
TooManyCards {
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digivolve_cards: usize,
|
||||
},
|
||||
|
||||
/// Unable to read card header
|
||||
#[display(fmt = "Unable to read card header for card id {}", id)]
|
||||
ReadCardHeader {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -137,7 +99,7 @@ pub enum DeserializeError {
|
||||
/// An unknown card type was found
|
||||
#[display(fmt = "Unknown card type for card id {}", id)]
|
||||
UnknownCardType {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: property::card_type::FromBytesError,
|
||||
},
|
||||
@@ -145,7 +107,7 @@ pub enum DeserializeError {
|
||||
/// Unable to read a card
|
||||
#[display(fmt = "Unable to read {} with id {}", card_type, id)]
|
||||
ReadCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
card_type: CardType,
|
||||
|
||||
#[error(source)]
|
||||
@@ -155,7 +117,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize a digimon card
|
||||
#[display(fmt = "Unable to deserialize digimon card with id {}", id)]
|
||||
DigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digimon::FromBytesError,
|
||||
},
|
||||
@@ -163,7 +125,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize an item card
|
||||
#[display(fmt = "Unable to deserialize item card with id {}", id)]
|
||||
ItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::item::FromBytesError,
|
||||
},
|
||||
@@ -171,7 +133,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize a digivolve card
|
||||
#[display(fmt = "Unable to deserialize digivolve card with id {}", id)]
|
||||
DigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digivolve::FromBytesError,
|
||||
},
|
||||
@@ -179,7 +141,7 @@ pub enum DeserializeError {
|
||||
/// Unable to read card footer
|
||||
#[display(fmt = "Unable to read card footer for card id {}", id)]
|
||||
ReadCardFooter {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -209,15 +171,15 @@ pub enum SerializeError {
|
||||
Table::MAX_BYTE_SIZE
|
||||
)]
|
||||
TooManyCards {
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digivolve_cards: usize,
|
||||
},
|
||||
|
||||
/// Unable to write a digimon card
|
||||
#[display(fmt = "Unable to write digimon card with id {}", id)]
|
||||
WriteDigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -225,7 +187,7 @@ pub enum SerializeError {
|
||||
/// Unable to write an item card
|
||||
#[display(fmt = "Unable to write item card with id {}", id)]
|
||||
WriteItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -233,7 +195,7 @@ pub enum SerializeError {
|
||||
/// Unable to write a digivolve card
|
||||
#[display(fmt = "Unable to write digivolve card with id {}", id)]
|
||||
WriteDigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -241,7 +203,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse a digimon card
|
||||
#[display(fmt = "Unable to parse digimon card with id {}", id)]
|
||||
ParseDigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digimon::ToBytesError,
|
||||
},
|
||||
@@ -249,7 +211,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse an item card
|
||||
#[display(fmt = "Unable to parse item card with id {}", id)]
|
||||
ParseItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::item::ToBytesError,
|
||||
},
|
||||
@@ -257,7 +219,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse a digivolve card
|
||||
#[display(fmt = "Unable to parse digivolve card with id {}", id)]
|
||||
ParseDigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digivolve::ToBytesError,
|
||||
},
|
||||
@@ -373,8 +335,8 @@ impl Table {
|
||||
// If the total table size is bigger than the max, return Err
|
||||
if table_size > Self::MAX_BYTE_SIZE {
|
||||
return Err(SerializeError::TooManyCards {
|
||||
digimon_cards: self.digimons.len(),
|
||||
item_cards: self.items.len(),
|
||||
digimon_cards: self.digimons.len(),
|
||||
item_cards: self.items.len(),
|
||||
digivolve_cards: self.digivolves.len(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ impl Bytes for Deck {
|
||||
unknown: [0xc],
|
||||
);
|
||||
|
||||
// Nanme / Owner
|
||||
// Name / Owner
|
||||
util::write_maybe_null_ascii_string(&self.name, bytes.name).map_err(ToBytesError::Name)?;
|
||||
util::write_maybe_null_ascii_string(&self.owner, bytes.owner).map_err(ToBytesError::Owner)?;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ pub enum DeserializeError {
|
||||
/// Could not read a deck entry
|
||||
#[display(fmt = "Unable to read deck entry with id {}", "id")]
|
||||
ReadDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -50,7 +50,7 @@ pub enum DeserializeError {
|
||||
/// Could not deserialize a deck entry
|
||||
#[display(fmt = "Unable to serialize deck entry with id {}", "id")]
|
||||
DeserializeDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: deck::FromBytesError,
|
||||
},
|
||||
@@ -71,7 +71,7 @@ pub enum SerializeError {
|
||||
/// Could not deserialize a deck entry
|
||||
#[display(fmt = "Unable to deserialize deck entry with id {}", "id")]
|
||||
SerializeDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: deck::ToBytesError,
|
||||
},
|
||||
@@ -79,7 +79,7 @@ pub enum SerializeError {
|
||||
/// Could not write a deck entry
|
||||
#[display(fmt = "Unable to read deck entry with id {}", "id")]
|
||||
WriteDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! 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 depracated and moved
|
||||
//! All items in this module will eventually be deprecated and moved
|
||||
//! somewhere else, but this change might take some time.
|
||||
|
||||
pub macro array_split {
|
||||
@@ -170,7 +170,7 @@ pub fn write_null_ascii_string<'a>(input: &ascii::AsciiStr, buf: &'a mut [u8]) -
|
||||
// If the input string doesn't fit into the buffer (excluding the null byte), return Err
|
||||
if input.len() >= buf.len() {
|
||||
return Err(WriteNullAsciiStringError::TooLarge {
|
||||
input_len: input.len(),
|
||||
input_len: input.len(),
|
||||
buffer_len: buf.len(),
|
||||
});
|
||||
}
|
||||
@@ -198,7 +198,7 @@ pub fn write_maybe_null_ascii_string<'a>(input: &ascii::AsciiStr, buf: &'a mut [
|
||||
// If the input string doesn't fit into the buffer, return Err
|
||||
if input.len() > buf.len() {
|
||||
return Err(WriteMaybeNullAsciiStringError::TooLarge {
|
||||
input_len: input.len(),
|
||||
input_len: input.len(),
|
||||
buffer_len: buf.len(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! The Io module takes care of interacting with the game file itself, such
|
||||
//! as ensuring that only the data sections in the game file are written to.
|
||||
//! As well as making convertions between coordinates in data to real file
|
||||
//! As well as making conversions between coordinates in data to real file
|
||||
//! coordinates. (For more details, visit the [`address`] module)
|
||||
|
||||
// Modules
|
||||
|
||||
@@ -39,10 +39,10 @@ impl std::convert::TryFrom<Real> for Data {
|
||||
// The data address is just converting the real_sector
|
||||
// to a data_sector and subtracting the header from the
|
||||
// real offset to get the data offset
|
||||
#[rustfmt::skip]
|
||||
Ok(Self::from(
|
||||
Real::SECTOR_BYTE_SIZE * real_sector + // Base of data sector
|
||||
real_sector_offset -
|
||||
Real::HEADER_BYTE_SIZE, // Data offset
|
||||
Real::SECTOR_BYTE_SIZE * real_sector + // Base of data sector
|
||||
real_sector_offset - Real::HEADER_BYTE_SIZE, // Data offset (skipping header)
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,13 @@ impl From<Data> for Real {
|
||||
let data_sector = data_address.sector();
|
||||
let data_sector_offset = data_address.offset();
|
||||
|
||||
// Then the real address is just convering the data_sector
|
||||
// Then the real address is just converting the data_sector
|
||||
// to a real_sector and adding the header plus the offset
|
||||
#[rustfmt::skip]
|
||||
Self::from(
|
||||
Self::SECTOR_BYTE_SIZE * data_sector + // Base of real sector
|
||||
Self::HEADER_BYTE_SIZE + // Skip header
|
||||
data_sector_offset, // Offset inside data sector
|
||||
data_sector_offset, // Offset inside data sector
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ impl Real {
|
||||
let real_sector = self.sector();
|
||||
|
||||
// The end of the real data section is after the header and data sections
|
||||
#[rustfmt::skip]
|
||||
Self::from(
|
||||
Self::SECTOR_BYTE_SIZE * real_sector + // Beginning of sector
|
||||
Self::HEADER_BYTE_SIZE + // Skip Header
|
||||
|
||||
@@ -69,7 +69,7 @@ impl<R: Read + Write + Seek> Read for GameFile<R> {
|
||||
// While the buffer isn't empty
|
||||
while !buf.is_empty() {
|
||||
// Get the current real address we're at in the reader
|
||||
// Note: If we can't get the position, we return immediatly
|
||||
// Note: If we can't get the position, we return immediately
|
||||
let cur_real_address = RealAddress::from(self.reader.stream_position()?);
|
||||
|
||||
// Get the data section end
|
||||
@@ -77,7 +77,7 @@ impl<R: Read + Write + Seek> Read for GameFile<R> {
|
||||
|
||||
// If we're at the end of the data section, seek to the next data section
|
||||
if cur_real_address == data_section_end {
|
||||
// Seek ahead by skiping the footer and next header
|
||||
// Seek ahead by skipping the footer and next header
|
||||
self.reader.seek(std::io::SeekFrom::Current(
|
||||
(RealAddress::FOOTER_BYTE_SIZE + RealAddress::HEADER_BYTE_SIZE) as i64,
|
||||
))?;
|
||||
@@ -106,7 +106,7 @@ impl<R: Read + Write + Seek> Read for GameFile<R> {
|
||||
}
|
||||
|
||||
// Read either until the end of the data section or until buffer is full
|
||||
// Note: If any fail, we immediatly return Err
|
||||
// Note: If any fail, we immediately return Err
|
||||
let bytes_read = self.reader.read(&mut buf[0..bytes_to_read])?;
|
||||
|
||||
// If 0 bytes were read, EOF was reached, so return with however many we've read
|
||||
@@ -137,7 +137,7 @@ impl<R: Read + Write + Seek> Write for GameFile<R> {
|
||||
// While the buffer isn't empty
|
||||
while !buf.is_empty() {
|
||||
// Get the current real address we're at in the reader
|
||||
// Note: If we can't get the position, we return immediatly
|
||||
// Note: If we can't get the position, we return immediately
|
||||
let cur_real_address = RealAddress::from(self.reader.stream_position()?);
|
||||
|
||||
// Get the data section end
|
||||
@@ -145,7 +145,7 @@ impl<R: Read + Write + Seek> Write for GameFile<R> {
|
||||
|
||||
// If we're at the end of the data section, seek to the next data section
|
||||
if cur_real_address == data_section_end {
|
||||
// Seek ahead by skiping the footer and next header
|
||||
// Seek ahead by skipping the footer and next header
|
||||
self.reader.seek(std::io::SeekFrom::Current(
|
||||
(RealAddress::FOOTER_BYTE_SIZE + RealAddress::HEADER_BYTE_SIZE) as i64,
|
||||
))?;
|
||||
@@ -174,7 +174,7 @@ impl<R: Read + Write + Seek> Write for GameFile<R> {
|
||||
}
|
||||
|
||||
// Write either until the end of the data section or until buffer runs out
|
||||
// Note: If this fails, we immediatly return Err
|
||||
// Note: If this fails, we immediately return Err
|
||||
let bytes_written = self.reader.write(&buf[0..bytes_to_write])?;
|
||||
|
||||
// If 0 bytes were written, EOF was reached, so return with however many we've read
|
||||
|
||||
91
src/lib.rs
91
src/lib.rs
@@ -1,10 +1,16 @@
|
||||
//! `dcb` is a library for interacting with the game file of `Digimon Digital Card Battle`,
|
||||
//! a PSX game.
|
||||
//! `dcb` is a library for interacting with the game file of `Digimon Digital Card Battle`.
|
||||
//!
|
||||
//! # Modules
|
||||
//! `dcb` splits itself into 2 main modules, [`io`], which interacts with the game file
|
||||
//! as well as general input / output operations and [`game`], where most of the game's
|
||||
//! data types are defined.
|
||||
//! `dcb` is split across 2 main modules, [`io`] and [`game`].
|
||||
//!
|
||||
//! ## Io
|
||||
//! The Io module is responsible for interacting with the game file. In the future it may be responsible
|
||||
//! for also interacting with the game extracted database, once work on that is complete.
|
||||
//!
|
||||
//! ## Game
|
||||
//! The game module is responsible for representing in-game structures such as cards, sprites, text, and
|
||||
//! others. The trait has various interfaces to be able to deserialize these structures from both the game
|
||||
//! file, database or even other sources, depending on the structure.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
@@ -32,36 +38,65 @@
|
||||
stmt_expr_attributes,
|
||||
unwrap_infallible,
|
||||
const_if_match,
|
||||
exclusive_range_pattern
|
||||
exclusive_range_pattern,
|
||||
external_doc
|
||||
)]
|
||||
// Lints
|
||||
#![warn(clippy::restriction, clippy::pedantic, clippy::nursery)]
|
||||
// Necessary items may be inlined using `LTO`, so we don't need to mark them as inline
|
||||
#![allow(clippy::missing_inline_in_public_items)]
|
||||
// We prefer tail returns where possible, as they help with code readability in most cases.
|
||||
#![allow(clippy::implicit_return)]
|
||||
// Very useful for arguments such as `arg: impl Into<U>`, then used
|
||||
// with `let arg = arg.into()`. As well as just going from `Option<T>`
|
||||
// to `T` without needing to change their names.
|
||||
#![allow(clippy::shadow_reuse, clippy::shadow_same)]
|
||||
// We use `.expect("...")` when we either know we cannot panic or it
|
||||
// is the safest alternative, as proceeding would corrupt the program state.
|
||||
#![allow(clippy::result_expect_used, clippy::option_expect_used)]
|
||||
// Like-wise with `.expect()`, we use `unreachable!` when we know a branch
|
||||
// if unreachable, and if it ever does get reached, panicking would be the
|
||||
// safest option
|
||||
#![allow(clippy::unreachable)]
|
||||
// We find it more important to be able to copy paste literals such as `0xabcd1234` than
|
||||
// being able to read them, which does not provide many benefits
|
||||
#![allow(clippy::unreadable_literal, clippy::unseparated_literal_suffix)]
|
||||
// We separate implementations per their functionality usually, such as constructors, getters, setters, and others.
|
||||
#![allow(clippy::multiple_inherent_impl)]
|
||||
// Many operations we need to repeat, and to keep symmetry
|
||||
#![allow(clippy::identity_op)]
|
||||
// We only introduce items before their first usage, which sometimes is half-way through the code
|
||||
#![allow(clippy::items_after_statements)]
|
||||
// Useful for when they either change a lot with new variants / data,
|
||||
// or for symmetry purposes
|
||||
#![allow(clippy::match_same_arms)]
|
||||
// In this library we have very grain-level error types, each function
|
||||
// will have it's own error type ideally, so any errors are explicit
|
||||
// by the type, without needing a section for them
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
// Incomplete code should be tagged as `todo`. In future versions of the library,
|
||||
// this lint may be removed, as incomplete code should not lie on a master branch.
|
||||
#![allow(clippy::todo)]
|
||||
// Although we generally try to avoid this, this can happen due to our module organization.
|
||||
// In the future, this lint should be removed globally and only enabled for modules which
|
||||
// actually require the use of it.
|
||||
#![allow(clippy::module_inception)]
|
||||
// False positives:
|
||||
// TODO: Remove them in the future once they are no longer triggered.
|
||||
// We only slice arrays, which are verified at compile time. This
|
||||
// lint currently triggers for `&[T; N]`, which we pass around a lot.
|
||||
#![allow(clippy::indexing_slicing)]
|
||||
// We don't have any `unsafe` impl for types that derive `Deserialize`.
|
||||
#![allow(clippy::unsafe_derive_deserialize)]
|
||||
// Banning arithmetic is too strict for this project
|
||||
#![allow(clippy::integer_arithmetic)]
|
||||
// TODO: Remove once fixed
|
||||
#![allow(
|
||||
clippy::missing_inline_in_public_items, // Dubious lint
|
||||
clippy::implicit_return, // We prefer tail returns where possible
|
||||
clippy::shadow_reuse, // Very useful for arguments `arg: impl Into<U>; let arg = arg.into()`
|
||||
clippy::if_not_else, // Sometimes it's easier to read with a negation
|
||||
clippy::result_expect_used,
|
||||
clippy::option_expect_used, // We use `.expect` when there is no safe alternative and the program is corrupt
|
||||
clippy::unreadable_literal, // More important to be able to copy the number with no formatting than it being readable
|
||||
clippy::multiple_inherent_impl, // We prefer to separate certain methods by type and insert error types in between methods
|
||||
clippy::identity_op, // Makes sense sometimes for symmetry
|
||||
clippy::items_after_statements, // Sometimes we only introduce items when we first use them.
|
||||
clippy::unseparated_literal_suffix, // We only separate them when they are long
|
||||
clippy::match_same_arms, // Sometimes we separate them for clarify and order
|
||||
clippy::missing_errors_doc, // We provide documentation on errors on the error type itself
|
||||
clippy::todo, // Code that is incomplete should be tagged as such.
|
||||
clippy::unreachable, // Some code should be unreachable and panic when reached.
|
||||
clippy::integer_arithmetic, // Come on now, we need to use numbers to program
|
||||
clippy::shadow_same, // Useful when taking arguments such as `value: impl AsRef<T>` / `let value = value.as_ref();`
|
||||
clippy::module_inception, // Sometimes module organization causes this
|
||||
clippy::missing_docs_in_private_items, // Not all private items are documented on purpose
|
||||
clippy::indexing_slicing, // False-positives on arrays
|
||||
// TODO: Deal with casts eventually
|
||||
clippy::missing_docs_in_private_items,
|
||||
clippy::as_conversions,
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_possible_truncation
|
||||
)]
|
||||
|
||||
// Modules
|
||||
|
||||
Reference in New Issue
Block a user