savestate: add various TryFrom impl for Moves and Move

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2020-06-30 15:21:44 +02:00
parent 08ad8073c8
commit ea93ad32cb
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2

View file

@ -321,22 +321,30 @@ impl fmt::Debug for Move {
} }
} }
impl TryFrom<&[u8; 2]> for Move { impl TryFrom<(u8, u8)> for Move {
type Error = Error; type Error = Error;
fn try_from(data: &[u8; 2]) -> Result<Move, Error> { fn try_from((id, pp): (u8, u8)) -> Result<Move, Error> {
if data[0x0] > 165 { // Gen1 doesn't have more than that number of moves if id > 165 { // Gen1 doesn't have more than that number of moves
return Err(Error::InvalidPokemonMove); return Err(Error::InvalidPokemonMove);
} }
Ok(Move { Ok(Move {
id: data[0x0], id: id,
pp: data[0x1] & 0b00111111, pp: pp & 0b00111111,
up: PPUp::try_from((data[0x1] & 0b11000000) >> 6)?, up: PPUp::try_from((pp & 0b11000000) >> 6)?,
}) })
} }
} }
impl TryFrom<&[u8; 2]> for Move {
type Error = Error;
fn try_from(data: &[u8; 2]) -> Result<Move, Error> {
Move::try_from((data[0], data[1]))
}
}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Moves([Option<Move>; 4]); pub struct Moves([Option<Move>; 4]);
@ -348,35 +356,33 @@ impl Deref for Moves {
} }
} }
impl TryFrom<&[u8]> for Moves { impl TryFrom<(&[u8], &[u8])> for Moves {
type Error = Error; type Error = Error;
fn try_from(data: &[u8]) -> Result<Moves, Error> { fn try_from(data: (&[u8], &[u8])) -> Result<Moves, Error> {
let data: &[u8; 8] = data.try_into()?; let moves: &[u8; 4] = data.0.try_into()?;
Moves::try_from(data) 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; type Error = Error;
fn try_from(data: &[u8; 8]) -> Result<Moves, Error> { fn try_from((moves, pps): (&[u8; 4], &[u8; 4])) -> Result<Moves, Error> {
const PP_OFFSET: usize = 0x4;
let array: [Option<Move>; 4] = [None; 4]; let array: [Option<Move>; 4] = [None; 4];
let mut vec = array.to_vec(); let mut vec = array.to_vec();
for i in 0..4 { for i in 0..4 {
if data[i] == 0x0 { if moves[i] == 0x0 {
continue; continue;
} }
let sub: [u8; 2] = [data[i], data[PP_OFFSET + i]]; vec[i] = Some(Move::try_from((moves[i], pps[i]))?);
vec[i] = Some(Move::try_from(&sub)?);
} }
let foo: [Option<Move>; 4] = vec.as_slice().try_into()?; let tmp: [Option<Move>; 4] = vec.as_slice().try_into()?;
Ok(Moves (foo)) Ok(Moves (tmp))
} }
} }
@ -551,9 +557,7 @@ impl TryFrom<&[u8]> for IndividualPk {
(data[PK_XP_OFFSET + 0x2] as u32) (data[PK_XP_OFFSET + 0x2] as u32)
}; };
let original_trainer: u16 = u16::from_be_bytes(data[PK_OT_RANGE].try_into().unwrap()); let original_trainer: u16 = u16::from_be_bytes(data[PK_OT_RANGE].try_into().unwrap());
let mut moves_data: Vec<u8> = data[PK_MOVES_RANGE].to_vec(); let moves = Moves::try_from((&data[PK_MOVES_RANGE], &data[PK_PP_RANGE]))?;
moves_data.extend_from_slice(&data[PK_PP_RANGE]);
let moves = Moves::try_from(moves_data.as_slice())?;
Ok(IndividualPk { Ok(IndividualPk {
_data: data.to_vec(), _data: data.to_vec(),
@ -574,7 +578,10 @@ impl TryFrom<&[u8]> for IndividualPk {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::convert::TryFrom; 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] = [ const KADABRA: [u8; 44] = [
// Species id // Species id
@ -675,10 +682,32 @@ mod tests {
].into()); ].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] #[test]
fn test_move_ppup() { fn test_move_ppup() {
let data: [u8; 2] = [0x65, 0x52]; let data: [u8; 2] = [0x65, 0x52];
let move1 = Move::try_from(&data).unwrap(); let move1 = Move::try_from(&data).unwrap();
assert_eq!(move1, Move { id: 0x65, pp: 18, up: PPUp::PPUp1 }); 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());
}
} }