fix: don't crash when failing to load/deserialize active runtime or openvrpaths (#28)

This commit is contained in:
Gabriele Musco 2023-06-21 07:11:50 +02:00
parent 82dde9750d
commit 9705f3d7e3
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
3 changed files with 72 additions and 36 deletions

View file

@ -1,7 +1,13 @@
use std::{fs::File, io::BufReader, path::Path};
use crate::{
file_utils::{
deserialize_file, get_writer, get_xdg_config_dir, get_xdg_data_dir, set_file_radonly,
},
paths::SYSTEM_PREFIX,
profile::Profile,
};
use expect_dialog::ExpectDialog;
use serde::{Deserialize, Serialize};
use crate::{file_utils::{get_xdg_config_dir, get_xdg_data_dir, get_writer, set_file_radonly}, profile::Profile, paths::SYSTEM_PREFIX};
use std::path::Path;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ActiveRuntimeInnerRuntime {
@ -31,18 +37,12 @@ pub fn is_steam(active_runtime: ActiveRuntime) -> bool {
}
}
fn get_active_runtime_from_path(path_s: String) -> Option<ActiveRuntime> {
let path = Path::new(&path_s);
if !(path.is_file() || path.is_symlink()) {
return None;
}
let fd = File::open(path).expect_dialog("Unable to open active_runtime.json");
let reader = BufReader::new(fd);
Some(serde_json::from_reader(reader).expect_dialog("Failed to deserialize active_runtime.json"))
fn get_active_runtime_from_path(path_s: &String) -> Option<ActiveRuntime> {
deserialize_file(path_s)
}
pub fn get_current_active_runtime() -> Option<ActiveRuntime> {
get_active_runtime_from_path(get_active_runtime_json_path())
get_active_runtime_from_path(&get_active_runtime_json_path())
}
fn dump_active_runtime_to_path(active_runtime: ActiveRuntime, path_s: String) {
@ -81,10 +81,7 @@ fn build_profile_active_runtime(profile: Profile) -> ActiveRuntime {
runtime: ActiveRuntimeInnerRuntime {
name: None,
valve_runtime_is_steamvr: None,
library_path: format!(
"{prefix}/lib/libopenxr_monado.so",
prefix = profile.prefix
),
library_path: format!("{prefix}/lib/libopenxr_monado.so", prefix = profile.prefix),
},
}
}
@ -96,10 +93,16 @@ pub fn set_current_active_runtime_to_profile(profile: Profile) {
if pfx == SYSTEM_PREFIX {
let path_s = get_active_runtime_json_path();
let path = Path::new(&path_s);
let mut rel_chain = path.components().map(|c| String::from("..")).collect::<Vec<String>>();
let mut rel_chain = path
.components()
.map(|_| String::from(".."))
.collect::<Vec<String>>();
rel_chain.pop();
rel_chain.pop();
ar.runtime.library_path = format!("{rels}/usr/lib/libopenxr_monado.so", rels = rel_chain.join("/"));
ar.runtime.library_path = format!(
"{rels}/usr/lib/libopenxr_monado.so",
rels = rel_chain.join("/")
);
}
dump_current_active_runtime(ar);
}
@ -113,7 +116,7 @@ mod tests {
#[test]
fn can_read_active_runtime_json_steamvr() {
let ar = get_active_runtime_from_path("./test/files/active_runtime.json.steamvr".into())
let ar = get_active_runtime_from_path(&"./test/files/active_runtime.json.steamvr".into())
.unwrap();
assert_eq!(ar.file_format_version, "1.0.0");
assert!(ar.runtime.valve_runtime_is_steamvr.unwrap());

View file

@ -1,10 +1,12 @@
use std::{fs::File, io::BufReader, path::Path};
use crate::{
file_utils::{
deserialize_file, get_writer, get_xdg_config_dir, get_xdg_data_dir, set_file_radonly,
},
profile::Profile,
};
use expect_dialog::ExpectDialog;
use serde::{Deserialize, Serialize};
use crate::{file_utils::{get_xdg_config_dir, get_xdg_data_dir, get_writer, set_file_radonly}, profile::Profile};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OpenVrPaths {
config: Vec<String>,
@ -33,18 +35,12 @@ pub fn is_steam(ovr_paths: OpenVrPaths) -> bool {
.is_some()
}
fn get_openvrpaths_from_path(path_s: String) -> Option<OpenVrPaths> {
let path = Path::new(&path_s);
if !(path.is_file() || path.is_symlink()) {
return None;
}
let fd = File::open(path).expect_dialog("Unable to open openvrpaths.vrpath");
let reader = BufReader::new(fd);
Some(serde_json::from_reader(reader).expect_dialog("Failed to deserialize openvrpaths.vrpath"))
fn get_openvrpaths_from_path(path_s: &String) -> Option<OpenVrPaths> {
deserialize_file(path_s)
}
pub fn get_current_openvrpaths() -> Option<OpenVrPaths> {
get_openvrpaths_from_path(get_openvrpaths_vrpath_path())
get_openvrpaths_from_path(&get_openvrpaths_vrpath_path())
}
fn dump_openvrpaths_to_path(ovr_paths: OpenVrPaths, path_s: String) {
@ -65,7 +61,10 @@ fn build_steam_openvrpaths() -> OpenVrPaths {
external_drivers: None,
jsonid: "vrpathreg".into(),
log: vec![format!("{data}/Steam/logs", data = datadir)],
runtime: vec![format!("{data}/Steam/steamapps/common/SteamVR", data = datadir)],
runtime: vec![format!(
"{data}/Steam/steamapps/common/SteamVR",
data = datadir
)],
version: 1,
}
}
@ -81,7 +80,10 @@ fn build_profile_openvrpaths(profile: Profile) -> OpenVrPaths {
external_drivers: None,
jsonid: "vrpathreg".into(),
log: vec![format!("{data}/Steam/logs", data = datadir)],
runtime: vec![format!("{opencomp_dir}/build", opencomp_dir = profile.opencomposite_path)],
runtime: vec![format!(
"{opencomp_dir}/build",
opencomp_dir = profile.opencomposite_path
)],
version: 1,
}
}
@ -96,7 +98,7 @@ mod tests {
#[test]
fn can_read_openvrpaths_vrpath_steamvr() {
let ovrp = get_openvrpaths_from_path("./test/files/openvrpaths.vrpath".into()).unwrap();
let ovrp = get_openvrpaths_from_path(&"./test/files/openvrpaths.vrpath".into()).unwrap();
assert_eq!(ovrp.config.len(), 1);
assert_eq!(
ovrp.config.get(0).unwrap(),

View file

@ -2,8 +2,8 @@ use crate::{constants::CMD_NAME, runner::Runner};
use expect_dialog::ExpectDialog;
use std::{
env,
fs::{self, create_dir_all, OpenOptions},
io::BufWriter,
fs::{self, create_dir_all, OpenOptions, File},
io::{BufWriter, BufReader},
path::Path,
};
@ -26,6 +26,37 @@ pub fn get_writer(path_s: &String) -> BufWriter<std::fs::File> {
BufWriter::new(file)
}
pub fn get_reader(path_s: &String) -> Option<BufReader<File>> {
let path = Path::new(&path_s);
if !(path.is_file() || path.is_symlink()) {
return None;
}
match File::open(path) {
Err(e) => {
println!("Error opening {}: {}", path_s, e);
return None;
}
Ok(fd) => {
Some(BufReader::new(fd))
}
}
}
pub fn deserialize_file<T: serde::de::DeserializeOwned>(path_s: &String) -> Option<T> {
match get_reader(&path_s) {
None => None,
Some(reader) => {
match serde_json::from_reader(reader) {
Err(e) => {
println!("Failed to deserialize {}: {}", path_s, e);
None
}
Ok(res) => Some(res)
}
}
}
}
pub fn get_home_dir() -> String {
env::var("HOME").expect_dialog("HOME env var not defined")
}