From ea93ad32cb27e8d5273d4c4598cae9853f96489b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Tue, 30 Jun 2020 15:21:44 +0200 Subject: [PATCH] savestate: add various TryFrom impl for Moves and Move MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- savestate/src/species.rs | 75 ++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/savestate/src/species.rs b/savestate/src/species.rs index 7490740..b54d7e5 100644 --- a/savestate/src/species.rs +++ b/savestate/src/species.rs @@ -321,22 +321,30 @@ impl fmt::Debug for Move { } } -impl TryFrom<&[u8; 2]> for Move { +impl TryFrom<(u8, u8)> for Move { type Error = Error; - fn try_from(data: &[u8; 2]) -> Result { - if data[0x0] > 165 { // Gen1 doesn't have more than that number of moves + fn try_from((id, pp): (u8, u8)) -> Result { + if id > 165 { // Gen1 doesn't have more than that number of moves return Err(Error::InvalidPokemonMove); } Ok(Move { - id: data[0x0], - pp: data[0x1] & 0b00111111, - up: PPUp::try_from((data[0x1] & 0b11000000) >> 6)?, + id: id, + pp: pp & 0b00111111, + up: PPUp::try_from((pp & 0b11000000) >> 6)?, }) } } +impl TryFrom<&[u8; 2]> for Move { + type Error = Error; + + fn try_from(data: &[u8; 2]) -> Result { + Move::try_from((data[0], data[1])) + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct Moves([Option; 4]); @@ -348,35 +356,33 @@ impl Deref for Moves { } } -impl TryFrom<&[u8]> for Moves { +impl TryFrom<(&[u8], &[u8])> for Moves { type Error = Error; - fn try_from(data: &[u8]) -> Result { - let data: &[u8; 8] = data.try_into()?; - Moves::try_from(data) + fn try_from(data: (&[u8], &[u8])) -> Result { + let moves: &[u8; 4] = data.0.try_into()?; + let pps: &[u8; 4] = data.1.try_into()?; + Moves::try_from((moves, pps)) } } -impl TryFrom<&[u8; 8]> for Moves { +impl TryFrom<(&[u8; 4], &[u8; 4])> for Moves { type Error = Error; - fn try_from(data: &[u8; 8]) -> Result { - const PP_OFFSET: usize = 0x4; + fn try_from((moves, pps): (&[u8; 4], &[u8; 4])) -> Result { let array: [Option; 4] = [None; 4]; let mut vec = array.to_vec(); for i in 0..4 { - if data[i] == 0x0 { + if moves[i] == 0x0 { continue; } - let sub: [u8; 2] = [data[i], data[PP_OFFSET + i]]; - - vec[i] = Some(Move::try_from(&sub)?); + vec[i] = Some(Move::try_from((moves[i], pps[i]))?); } - let foo: [Option; 4] = vec.as_slice().try_into()?; - Ok(Moves (foo)) + let tmp: [Option; 4] = vec.as_slice().try_into()?; + Ok(Moves (tmp)) } } @@ -551,9 +557,7 @@ impl TryFrom<&[u8]> for IndividualPk { (data[PK_XP_OFFSET + 0x2] as u32) }; let original_trainer: u16 = u16::from_be_bytes(data[PK_OT_RANGE].try_into().unwrap()); - let mut moves_data: Vec = data[PK_MOVES_RANGE].to_vec(); - moves_data.extend_from_slice(&data[PK_PP_RANGE]); - let moves = Moves::try_from(moves_data.as_slice())?; + let moves = Moves::try_from((&data[PK_MOVES_RANGE], &data[PK_PP_RANGE]))?; Ok(IndividualPk { _data: data.to_vec(), @@ -574,7 +578,10 @@ impl TryFrom<&[u8]> for IndividualPk { #[cfg(test)] mod tests { use std::convert::TryFrom; - use crate::species::{EV, IndividualPk, IV, Move, PPUp, PKTypes, PKType, Species, StatusConditions}; + use crate::species::{ + EV, IndividualPk, IV, Moves, Move, PPUp, + PKTypes, PKType, Species, StatusConditions, + }; const KADABRA: [u8; 44] = [ // Species id @@ -675,10 +682,32 @@ mod tests { ].into()); } + #[test] + fn test_move_try_from() { + let data1: (u8, u8) = (0x65, 0x52); + let move1 = Move::try_from(data1).unwrap(); + let data2: &[u8; 2] = &[0x65, 0x52]; + let move2 = Move::try_from(data2).unwrap(); + assert_eq!(move1, Move { id: 0x65, pp: 18, up: PPUp::PPUp1 }); + assert_eq!(move1, move2); + } + #[test] fn test_move_ppup() { let data: [u8; 2] = [0x65, 0x52]; let move1 = Move::try_from(&data).unwrap(); assert_eq!(move1, Move { id: 0x65, pp: 18, up: PPUp::PPUp1 }); } + + #[test] + fn test_moves_try_from() { + let moves: [u8; 4] = [0x64, 0x5d, 0x0, 0x0]; + let pps: [u8; 4] = [0x14, 0x19, 0x0, 0x0]; + let results = Moves::try_from((&moves, &pps)).unwrap(); + assert_eq!(results, [ + Some(Move { id: 0x64, pp: 20, up: PPUp::None }), + Some(Move { id: 0x5d, pp: 25, up: PPUp::None }), + None, None, + ].into()); + } }