Skip to content

Commit

Permalink
Error changes
Browse files Browse the repository at this point in the history
  • Loading branch information
TCA166 committed Dec 25, 2024
1 parent d464eb8 commit b3440d0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/display/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ fn create_title_province_map(game_path: &str) -> HashMap<String, GameId> {
let path = game_path.to_owned() + "/common/landed_titles/00_landed_titles.txt";
let file = SaveFile::open(&path).unwrap();
let mut map = HashMap::default();
for mut title in file {
let title_object = title.parse().unwrap();
for title in file {
let title_object = title.unwrap().parse().unwrap();
//DFS in the structure
let mut stack = vec![title_object.as_map()];
while let Some(o) = stack.pop() {
Expand Down
20 changes: 12 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ impl Debug for UserError {
}
}

impl From<SaveFileError> for UserError {
fn from(value: SaveFileError) -> Self {
return UserError::FileError(value);
}
}

/// Main function. This is the entry point of the program.
///
/// # Process
Expand Down Expand Up @@ -132,19 +138,17 @@ fn main() -> Result<(), UserError> {
}
localizer.resolve();
//initialize the save file
let save = match SaveFile::open(args.filename.as_str()) {
Ok(s) => s,
Err(e) => return Err(UserError::FileError(e)),
};
let save = SaveFile::open(args.filename.as_str())?;
// this is sort of like the first round of filtering where we store the objects we care about
let mut game_state: GameState = GameState::new();
let mut players: Vec<Player> = Vec::new();
let progress_bar = ProgressBar::new(save.len() as u64);
progress_bar.set_style(bar_style.clone());
for mut i in progress_bar.wrap_iter(save.into_iter()) {
progress_bar.set_message(i.get_name().to_owned());
// TODO make this return a Result
process_section(&mut i, &mut game_state, &mut players);
for i in progress_bar.wrap_iter(save.into_iter()) {
let mut section = i.unwrap();
progress_bar.set_message(section.get_name().to_owned());
// if an error occured somewhere here, there's nothing we can do
process_section(&mut section, &mut game_state, &mut players).unwrap();
}
progress_bar.finish_with_message("Save parsing complete");
//prepare things for rendering
Expand Down
36 changes: 21 additions & 15 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub use save_file::{SaveFile, SaveFileError};
/// A submodule that provides the [Section] object, which is used to store the parsed data of a section of the save file.
mod section;
use section::Section;
pub use section::SectionError;

/// A submodule that provides the [GameState] object, which is used as a sort of a dictionary.
/// CK3 save files have a myriad of different objects that reference each other, and in order to allow for centralized storage and easy access, the [GameState] object is used.
Expand All @@ -26,21 +27,25 @@ use super::{
/// A function that processes a section of the save file.
/// Based on the given section, it will update the [GameState] object and the [Player] vector.
/// The [GameState] object is used to store all the data from the save file, while the [Player] vector is used to store the player data.
pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mut Vec<Player>) {
pub fn process_section(
i: &mut Section,
game_state: &mut GameState,
players: &mut Vec<Player>,
) -> Result<(), SectionError> {
match i.get_name() {
"meta_data" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let r = r.as_map();
game_state.set_current_date(r.get_string_ref("meta_date"));
game_state.set_offset_date(r.get_string_ref("meta_real_date"));
}
//the order is kept consistent with the order in the save file
"traits_lookup" => {
let r = i.parse().unwrap();
let r = i.parse()?;
game_state.add_lookup(r.as_array().into_iter().map(|x| x.as_string()).collect());
}
"landed_titles" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let landed = r.as_map().get_object_ref("landed_titles").as_map();
for (_, v) in landed.into_iter() {
match v {
Expand All @@ -55,7 +60,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"county_manager" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let counties = r.as_map().get_object_ref("counties").as_map();
// we create an association between the county key and the faith and culture of the county
// this is so that we can easily add the faith and culture to the title, so O(n) instead of O(n^2)
Expand All @@ -82,7 +87,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"dynasties" => {
let r = i.parse().unwrap();
let r = i.parse()?;
for (_, d) in r.as_map().into_iter() {
match d.as_object() {
SaveFileObject::Map(o) => {
Expand All @@ -106,7 +111,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"living" => {
let r = i.parse().unwrap();
let r = i.parse()?;
for (_, l) in r.as_map().into_iter() {
match l {
SaveFileValue::Object(o) => {
Expand All @@ -120,7 +125,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"dead_unprunable" => {
let r = i.parse().unwrap();
let r = i.parse()?;
for (_, d) in r.as_map().into_iter() {
match d {
SaveFileValue::Object(o) => {
Expand All @@ -134,7 +139,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"characters" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let dead_prunable = r.as_map().get("dead_prunable");
if dead_prunable.is_some() {
for (_, d) in dead_prunable.unwrap().as_object().as_map().into_iter() {
Expand All @@ -151,7 +156,7 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"vassal_contracts" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let r = r.as_map();
// if version <= 1.12 then the key is active, otherwise it is database, why paradox?
let active = r
Expand All @@ -173,21 +178,21 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"religion" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let faiths = r.as_map().get_object_ref("faiths").as_map();
for (_, f) in faiths.into_iter() {
game_state.add_faith(f.as_object().as_map());
}
}
"culture_manager" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let cultures = r.as_map().get_object_ref("cultures").as_map();
for (_, c) in cultures.into_iter() {
game_state.add_culture(c.as_object().as_map());
}
}
"character_memory_manager" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let database = r.as_map().get_object_ref("database").as_map();
for (_, d) in database.into_iter() {
match d {
Expand All @@ -201,12 +206,12 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
}
}
"played_character" => {
let r = i.parse().unwrap();
let r = i.parse()?;
let p = Player::from_game_object(r.as_map(), game_state);
players.push(p);
}
"artifacts" => {
let artifacts = i.parse().unwrap();
let artifacts = i.parse()?;
let arr = artifacts.as_map().get_object_ref("artifacts").as_map();
for (_, a) in arr.into_iter() {
match a {
Expand All @@ -223,4 +228,5 @@ pub fn process_section(i: &mut Section, game_state: &mut GameState, players: &mu
i.skip();
}
}
return Ok(());
}
42 changes: 22 additions & 20 deletions src/parser/save_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,19 @@ impl SaveFile {
}

impl Iterator for SaveFile {
type Item = Section;
type Item = Result<Section, SaveFileError>;

/// Get the next object in the save file
/// If the file pointer has reached the end of the save file then it will return None.
fn next(&mut self) -> Option<Section> {
fn next(&mut self) -> Option<Self::Item> {
let mut key = String::new();
let off = self.offset.get_internal_mut();
for c in self.contents[*off..].chars() {
match c {
'}' | '"' => {
panic!("Unexpected character at {}", *off);
return Some(Err(SaveFileError::ParseError(
"Unexpected character encountered in-between sections",
)));
}
'{' => {
break;
Expand All @@ -180,11 +182,11 @@ impl Iterator for SaveFile {
if key.is_empty() {
return None;
}
return Some(Section::new(
return Some(Ok(Section::new(
key,
self.contents.clone(),
self.offset.clone(),
));
)));
}
}

Expand Down Expand Up @@ -214,7 +216,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2").as_map();
let test3 = test2.get_string_ref("test3");
Expand All @@ -235,7 +237,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2");
let test2_val = test2.as_array();
Expand Down Expand Up @@ -281,7 +283,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2").as_map();
assert_eq!(*(test2.get_string_ref("1")), "2".to_string());
Expand All @@ -297,7 +299,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2").as_array();
assert_eq!(*(test2.get_index(0).unwrap().as_string()), "1".to_string());
Expand Down Expand Up @@ -331,7 +333,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
let variables = object.as_map().get_object_ref("variables").as_map();
let data = variables.get_object_ref("data").as_array();
assert_ne!(data.len(), 0)
Expand Down Expand Up @@ -372,7 +374,7 @@ mod tests {
}
artifact_claims={ 83888519 }
}");
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "3623".to_string());
assert_eq!(
*(object.as_map().get_string_ref("name")),
Expand Down Expand Up @@ -414,7 +416,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2").as_map();
let test3 = test2.get_string_ref("test3");
Expand Down Expand Up @@ -474,7 +476,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "c_derby".to_string());
let b_derby = object.as_map().get_object_ref("b_derby").as_map();
assert_eq!(*(b_derby.get_string_ref("province")), "1621".to_string());
Expand Down Expand Up @@ -504,7 +506,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
let test2 = object.as_map().get_object_ref("test2").as_map();
let test3 = test2.get_string_ref("test3");
Expand All @@ -519,7 +521,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "test".to_string());
}

Expand All @@ -530,7 +532,7 @@ mod tests {
duration={ 2 0=7548 1=2096 }
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
assert_eq!(object.get_name(), "duration".to_string());
assert_eq!(object.as_array().len(), 3);
}
Expand All @@ -545,7 +547,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse().unwrap();
let object = save_file.next().unwrap().unwrap().parse().unwrap();
let arr = object.as_map().get_object_ref("a").as_array();
assert_eq!(arr.len(), 2);
}
Expand All @@ -560,7 +562,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse();
let object = save_file.next().unwrap().unwrap().parse();
assert!(object.is_err())
}

Expand All @@ -574,7 +576,7 @@ mod tests {
}
",
);
let object = save_file.next().unwrap().parse();
let object = save_file.next().unwrap().unwrap().parse();
assert!(object.is_err())
}
#[test]
Expand All @@ -594,7 +596,7 @@ mod tests {
b={
",
);
let object = save_file.next().unwrap().parse();
let object = save_file.next().unwrap().unwrap().parse();
assert!(object.is_err())
}
}

0 comments on commit b3440d0

Please sign in to comment.