Added start of config stuff
This commit is contained in:
@@ -7,4 +7,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
eframe = "0.21.3"
|
eframe = "0.21.3"
|
||||||
rfd = "*"
|
rfd = "0.11.4"
|
||||||
|
serde = "1.0.163"
|
||||||
|
serde_derive = "1.0.163"
|
||||||
|
toml = "0.7.4"
|
||||||
|
|||||||
102
src/config.rs
Normal file
102
src/config.rs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
use toml;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use crate::infos::{WadInfo, LauncherInfo};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Config {
|
||||||
|
iwads: Option<Vec<WadInfo>>,
|
||||||
|
pwads: Option<Vec<WadInfo>>,
|
||||||
|
launchers: Option<Vec<LauncherInfo>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_config(path: &PathBuf) -> Result<Config, Box<dyn std::error::Error>> {
|
||||||
|
let content = std::fs::read_to_string(&path)?;
|
||||||
|
Ok(toml::from_str(&content)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_config(path: &PathBuf, config: &Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let toml_string = toml::to_string(&config).unwrap();
|
||||||
|
Ok(std::fs::write(path, toml_string)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_iwad() {
|
||||||
|
let config_str = "[[iwads]]\n\
|
||||||
|
name = \"DOOM2.WAD\"\n\
|
||||||
|
path = \"/home/wads/doom.wad\"\n";
|
||||||
|
let config: Result<Config, _> = toml::from_str(&config_str);
|
||||||
|
assert!(config.is_ok());
|
||||||
|
let config = config.unwrap();
|
||||||
|
assert_eq!(config.iwads.unwrap().len(), 1);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn basic_iwads() {
|
||||||
|
let config_str = "[[iwads]]
|
||||||
|
name = \"DOOM2.WAD\"
|
||||||
|
path = \"/home/wads/doom.wad\"
|
||||||
|
|
||||||
|
[[iwads]]
|
||||||
|
name = \"DOOM1.WAD1.9\"
|
||||||
|
path = \"/home/wads/doom1.9.wad\"";
|
||||||
|
|
||||||
|
let config: Config = toml::from_str(&config_str).unwrap();
|
||||||
|
// I'm not 100% sure why I need all of these as_ref
|
||||||
|
assert_eq!(config.iwads.as_ref().unwrap().len(),2);
|
||||||
|
assert_eq!(config.iwads.as_ref().unwrap()[0].name,"DOOM2.WAD");
|
||||||
|
assert_eq!(config.iwads.as_ref().unwrap()[1].name,"DOOM1.WAD1.9");
|
||||||
|
assert_eq!(config.iwads.unwrap()[0].path, PathBuf::from("/home/wads/doom.wad"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iwads_and_pwads() {
|
||||||
|
let config_str = "[[iwads]]
|
||||||
|
name = \"DOOM2.WAD\"
|
||||||
|
path = \"/home/wads/doom.wad\"
|
||||||
|
|
||||||
|
[[iwads]]
|
||||||
|
name = \"DOOM1.WAD1.9\"
|
||||||
|
path = \"/home/wads/doom1.9.wad\"
|
||||||
|
|
||||||
|
[[pwads]]
|
||||||
|
name = \"Ancient Aliens\"
|
||||||
|
path = \"/home/pwads/aa.pk3\"";
|
||||||
|
|
||||||
|
let config: Config = toml::from_str(&config_str).unwrap();
|
||||||
|
assert_eq!(config.iwads.as_ref().unwrap().len(), 2);
|
||||||
|
assert_eq!(config.iwads.unwrap()[0].name, "DOOM2.WAD");
|
||||||
|
assert_eq!(config.pwads.as_ref().unwrap()[0].name, "Ancient Aliens");
|
||||||
|
assert_eq!(config.pwads.unwrap()[0].path, PathBuf::from("/home/pwads/aa.pk3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iwads_back_and_forth() {
|
||||||
|
let iwad1 = WadInfo {
|
||||||
|
path: PathBuf::from("/home/wads/doom.wad"),
|
||||||
|
name: "DOOM.WAD".to_string(),
|
||||||
|
};
|
||||||
|
let iwad2 = WadInfo {
|
||||||
|
path: PathBuf::from("/home/wads/doom2.wad"),
|
||||||
|
name: "DOOM2.WAD".to_string(),
|
||||||
|
};
|
||||||
|
let iwads = vec![iwad1, iwad2];
|
||||||
|
let launcher = LauncherInfo {
|
||||||
|
path: PathBuf::from("/home/bin/gzdoom/gzdoom"),
|
||||||
|
name: "GZDoom".to_string(),
|
||||||
|
};
|
||||||
|
let config = Config {
|
||||||
|
iwads: Some(iwads),
|
||||||
|
launchers: Some(vec![launcher]),
|
||||||
|
pwads: None,
|
||||||
|
};
|
||||||
|
let toml_as_str = toml::to_string(&config).unwrap();
|
||||||
|
let new_config: Config = toml::from_str(&toml_as_str).unwrap();
|
||||||
|
assert_eq!(config.iwads.unwrap().len(), new_config.iwads.unwrap().len());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
19
src/infos.rs
Normal file
19
src/infos.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
// TODO - write some impl stuff in here so the main GUI stuff
|
||||||
|
// is a little bit more decoupled from this. I think a Display
|
||||||
|
// and perhaps the path to string conversion too could be
|
||||||
|
// removed from the GUI part
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct WadInfo {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct LauncherInfo {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
33
src/main.rs
33
src/main.rs
@@ -1,5 +1,9 @@
|
|||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use infos::{WadInfo, LauncherInfo};
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
|
pub mod infos;
|
||||||
|
|
||||||
fn main() -> Result<(), eframe::Error> {
|
fn main() -> Result<(), eframe::Error> {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
@@ -13,16 +17,6 @@ fn main() -> Result<(), eframe::Error> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WadInfo {
|
|
||||||
path: PathBuf,
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LauncherInfo {
|
|
||||||
path: PathBuf,
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RustDoomLauncher {
|
struct RustDoomLauncher {
|
||||||
all_launchers: Vec<LauncherInfo>,
|
all_launchers: Vec<LauncherInfo>,
|
||||||
all_iwads: Vec<WadInfo>,
|
all_iwads: Vec<WadInfo>,
|
||||||
@@ -102,7 +96,6 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
});
|
});
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
// TODO add default name as the path or something
|
|
||||||
ui.label("Add WADs etc");
|
ui.label("Add WADs etc");
|
||||||
ui.set_max_width(180.0);
|
ui.set_max_width(180.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
@@ -110,7 +103,8 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
ui.text_edit_singleline(&mut self.name)
|
ui.text_edit_singleline(&mut self.name)
|
||||||
.labelled_by(name_label.id);
|
.labelled_by(name_label.id);
|
||||||
});
|
});
|
||||||
|
// It kind of feels like the right place to use a closure - unsure whether I need
|
||||||
|
// to pass both of these vaules in, or what the story is here.
|
||||||
let get_name = |path: &PathBuf, name: &String| {
|
let get_name = |path: &PathBuf, name: &String| {
|
||||||
if self.name.is_empty() {
|
if self.name.is_empty() {
|
||||||
// Check this perhaps? Unsure whether the FileDialog can actually
|
// Check this perhaps? Unsure whether the FileDialog can actually
|
||||||
@@ -125,7 +119,7 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||||
self.all_launchers.push(LauncherInfo {
|
self.all_launchers.push(LauncherInfo {
|
||||||
name: get_name(&path, &self.name),
|
name: get_name(&path, &self.name),
|
||||||
path: path
|
path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +127,7 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||||
self.all_iwads.push(WadInfo {
|
self.all_iwads.push(WadInfo {
|
||||||
name: get_name(&path, &self.name),
|
name: get_name(&path, &self.name),
|
||||||
path: path,
|
path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +135,7 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||||
self.all_pwads.push(WadInfo {
|
self.all_pwads.push(WadInfo {
|
||||||
name: get_name(&path, &self.name),
|
name: get_name(&path, &self.name),
|
||||||
path: path.clone(),
|
path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,9 +147,12 @@ impl eframe::App for RustDoomLauncher {
|
|||||||
// but it'll at least do the highlighting when hovered nicely
|
// but it'll at least do the highlighting when hovered nicely
|
||||||
if let Some(l) = self.selected_launcher {
|
if let Some(l) = self.selected_launcher {
|
||||||
if let Some(iwad) = self.all_launchers.get(l) {
|
if let Some(iwad) = self.all_launchers.get(l) {
|
||||||
if ui.add(egui::SelectableLabel::new(false, &iwad.name)).clicked() {
|
if ui
|
||||||
self.selected_launcher = None;
|
.add(egui::SelectableLabel::new(false, &iwad.name))
|
||||||
}
|
.clicked()
|
||||||
|
{
|
||||||
|
self.selected_launcher = None;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.selected_launcher = None;
|
self.selected_launcher = None;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user