fable/src/utilities/files.rs
2025-04-17 15:53:45 -06:00

122 lines
4.6 KiB
Rust

use std::{fs::File, io::Read};
use serde::de::DeserializeOwned;
use crate::{course::story, learner::profile::{self, Learner}};
// pub fn save_learner_progress(learner: &Learner, file: &str) -> Result<(), std::io::Error> {
// learner.clone().save_to_file(file)?;
// Ok(())
// }
pub fn get_previous_saves() -> Vec<String> {
let mut previous_saves = std::fs::read_dir("saves/")
.unwrap_or_else(|_| {
std::fs::create_dir_all("saves/").expect("Failed to create the saves/ directory");
std::fs::read_dir("saves/").expect("Failed to read the saves/ directory")
})
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
if path.extension()?.to_str()? == "json" {
let file_content = std::fs::read_to_string(&path).ok()?;
let learner: Learner = serde_json::from_str(&file_content).ok()?;
Some(learner.name)
} else {
None
}
})
.collect::<Vec<String>>();
previous_saves.push("Create New".to_string());
previous_saves
}
pub fn save_to_file(file: &str, learner: &Learner) -> Result<String, std::io::Error> {
match serde_json::to_string_pretty(learner) {
Ok(json_data) => match std::fs::write(file, json_data) {
Ok(_) => Ok(format!("File saved to {}", file.to_string())),
Err(e) => {
eprintln!("Error writing to file: {}", e);
Err(e)
}
},
Err(e) => {
eprintln!("Error serializing learner: {}", e);
Err(e.into())
}
}
}
pub fn load_from_file<T: DeserializeOwned>(filename: &str) -> Result<T, Box<dyn std::error::Error>> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let data = serde_json::from_str(&contents)?;
Ok(data)
}
// pub fn load_learner_progress() -> Result<Learner, std::io::Error> {
// let mut new_session: bool = false;
// let mut learner = {
// // Initialize the learner's progress
// // Check if a save file exists to load previous progress
// if std::path::Path::new(SAVE_FILE).exists() {
// match Learner::load_from_file(SAVE_FILE) {
// Ok(progress) => {
// print_boxed(&format!("Welcome back, {}! Let's continue your journey in FABLE.", progress.name), StatementType::Default );
// progress
// }
// Err(e) => {
// new_session = true;
// print_boxed(&format!("Couldn't load your save file due to error: {}.\nStarting a new learning experience.", e), StatementType::IncorrectFeedback );
// Learner::initialize_learner()
// }
// }
// } else {
// new_session = true;
// // Start a new session
// print_boxed("
// Welcome to FABLE, an interactive tutor for formal reasoning.
// Fallacy ~~~~~~~~~~~~
// Awareness and ~~~~~~
// Bias ~~~~~~~~~~~~~~~
// Learning ~~~~~~~~~~~
// Environment ~~~~~~~~", StatementType::Default);
// print_boxed("
// My name is Francis, and I am here to help you learn about formal reasoning.\n
// You see, many years ago, my people were nearly wiped out because of a lack of critical thinking.
// I have been programmed to help you avoid the same fate.\n
// In the next screen, you can select what you want to study.
// Choose wisely. The fate of your people depends on it.", StatementType::Default);
// Learner::initialize_learner()
// }
// };
// if !new_session {
// learner.display_progress();
// learner.confirm_course_selection(); // Confirm the course selection after reading the progress
// }
// let json_data = std::fs::read_to_string(SAVE_FILE)?;
// let progress: Learner = serde_json::from_str(&json_data)?;
// Ok(progress)
// }
// pub fn load_learner_progress() -> Result<Learner, std::io::Error> {
// let json_data = fs::read_to_string(SAVE_FILE)?;
// let progress: Learner = serde_json::from_str(&json_data)?;
// Ok(progress)
// }
pub fn sanitize_name(name: &str) -> String {
name.replace(|c: char| !c.is_alphanumeric(), "_").to_lowercase()
}
pub fn parse_unit(filename: &str) -> Result<story::UnitStory, Box<dyn std::error::Error>> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let data = serde_json::from_str(&contents)?;
Ok(data)
}