use std::{
error::{self, Error},
fs::OpenOptions,
io::{ self, LineWriter, Write },
path::Path,
result
};
use serde::{Deserialize, Serialize};
use serde_json;
use super::roster_extractor::TrainedCharacterData;
pub type ViewerId = u64;
pub type TrainedCharaId = u16;
pub type FactorId = u32;
pub type CardId = u32;
pub type WinSaddleId = u32;
pub type NicknameId = u32;
pub type Rank = u8;
pub type Rarity = u8;
pub type TalentLevel = u8;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct RaceResult {
pub turn: u8,
pub program_id: u32,
pub weather: u8,
pub ground_condition: u8,
pub running_style: u8,
pub popularity: u8,
pub result_rank: u8,
pub result_time: u32,
pub prize_money: u8
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SupportCard {
pub position: u8,
pub support_card_id: u32,
pub exp: u32,
pub limit_break_count: u8
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Skill {
pub skill_id: u32,
pub level: u8
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct FactorInfo {
pub factor_id: FactorId,
pub level: u8
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SuccessionHistory {
pub id: u32,
viewer_id: ViewerId,
pub trained_chara_id: TrainedCharaId,
pub history_type: u8,
pub succession_card_id: u32,
pub date: u32,
rental_viewer_id: u64,
pub user_name: String,
pub circle_name: String
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SuccessionCharacter {
pub position_id: u8,
pub card_id: CardId,
pub rank: Rank,
pub rarity: Rarity,
pub talent_level: TalentLevel,
pub factor_id_array: Vec<FactorId>,
pub factor_info_array: Vec<FactorInfo>,
pub win_saddle_id_array: Vec<WinSaddleId>,
owner_viewer_id: ViewerId
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct TrainedCharacter {
viewer_id: ViewerId,
pub trained_chara_id: TrainedCharaId,
owner_viewer_id: ViewerId,
pub owner_trained_chara_id: u16,
pub single_mode_chara_id: u8,
pub chara_seed: u64,
pub card_id: CardId,
pub succession_trained_chara_id_1: u32,
pub succession_trained_chara_id_2: u32,
pub use_type: u8,
pub speed: u16,
pub stamina: u16,
pub power: u16,
pub wiz: u16,
pub guts: u16,
pub fans: u64,
pub rank_score: u32,
pub rank: Rank,
pub scenario_id: u16,
pub route_id: u16,
pub arrive_route_race_id: u16,
pub proper_ground_turf: u8,
pub proper_ground_dirt: u8,
pub proper_running_style_nige: u8,
pub proper_running_style_senko: u8,
pub proper_running_style_sashi: u8,
pub proper_running_style_oikomi: u8,
pub proper_distance_short: u8,
pub proper_distance_mile: u8,
pub proper_distance_middle: u8,
pub proper_distance_long: u8,
pub succession_num: u8,
pub rarity: Rarity,
pub is_saved: u8,
pub is_locked: u8,
pub talent_level: TalentLevel,
pub race_cloth_id: u32,
pub chara_grade: u16,
pub running_style: u8,
pub nickname_id: NicknameId,
pub wins: u8,
pub register_time: String,
pub create_time: String,
pub skill_array: Vec<Skill>,
pub support_card_list: Vec<SupportCard>,
pub race_result_list: Vec<RaceResult>,
pub win_saddle_id_array: Vec<WinSaddleId>,
pub nickname_id_array: Vec<NicknameId>,
pub factor_id_array: Vec<FactorId>,
pub factor_info_array: Vec<FactorInfo>,
pub succession_chara_array: Vec<SuccessionCharacter>,
pub succession_history_array: Vec<SuccessionHistory>
}
pub fn deserialize_data(data: TrainedCharacterData) -> Result<Vec<TrainedCharacter>,rmp_serde::decode::Error> {
match rmp_serde::from_slice::<Vec<TrainedCharacter>>(&data) {
Ok(d) => return Ok(d),
Err(e) => return Err(e)
};
}
pub fn to_json_file(deser_data: &mut Vec<TrainedCharacter>, path: &Path) -> io::Result<()> {
for card in deser_data.iter_mut() {
card.viewer_id = 0;
card.owner_viewer_id = 0;
let _ = card.succession_chara_array.iter_mut()
.for_each(|s_char| s_char.owner_viewer_id = 0);
let _ = card.succession_history_array.iter_mut()
.for_each(|s_hist| {
s_hist.viewer_id = 0;
s_hist.rental_viewer_id = 0;
});
}
let json_string = match serde_json::to_string_pretty(&deser_data) {
Ok(str) => str,
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e))
};
match OpenOptions::new().write(true).create_new(true).open(path) {
Ok(outfile) => {
let mut line_writer = LineWriter::new(outfile);
line_writer.write_all(json_string.as_bytes())?;
line_writer.flush()?;
println!("Wrote file to: {}",path.display());
},
Err(err) => match err.kind() {
io::ErrorKind::AlreadyExists => match OpenOptions::new().write(true).truncate(true).open(path) {
Ok(outfile) => {
let mut line_writer = LineWriter::new(outfile);
line_writer.write_all(json_string.as_bytes())?;
line_writer.flush()?;
println!("Wrote file to: {}",path.display());
},
Err(e) => return Err(e)
},
e @ _ => return Err(io::Error::from(e))
}
}
Ok(())
}