From b6d25da7c24d1471578dc28cd6589a9a81e50968 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Sat, 28 Sep 2019 21:14:14 +0000 Subject: [PATCH] layout: Fallback to builtin before switching layouts When the user-provided layout was broken or missing, the loading would proceed with the fallback layout. It tries to load the builtin one first now. --- src/data.rs | 72 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/src/data.rs b/src/data.rs index 0fb1f280..44231643 100644 --- a/src/data.rs +++ b/src/data.rs @@ -94,36 +94,60 @@ impl fmt::Display for DataSource { /// If the layout exists, but is broken, fallback is activated. fn load_layout( name: &str -) -> (Result<::layout::Layout, LoadError>, DataSource) { +) -> ( + Result<::layout::Layout, LoadError>, // last attempted + DataSource, // last attempt source + Option<(LoadError, DataSource)>, // first attempt source +) { let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR") .map(PathBuf::from) .or_else(|| xdg::data_path("squeekboard/keyboards")) .map(|path| path.join(name).with_extension("yaml")); - let (layout, source) = match path { - Some(path) => {( + let layout = match path { + Some(path) => Some(( Layout::from_yaml_stream(path.clone()) - .map_err(|e| LoadError::BadData(e)), - DataSource::File(path) - )}, - None => {( - load_layout_from_resource(name), - DataSource::Resource(name.into()) - )}, + .map_err(LoadError::BadData), + DataSource::File(path), + )), + None => None, // No env var, not an error + }; + + let (failed_attempt, layout) = match layout { + Some((Ok(layout), path)) => (None, Some((layout, path))), + Some((Err(e), path)) => (Some((e, path)), None), + None => (None, None), }; + let (layout, source) = match layout { + Some((layout, path)) => (Ok(layout), path), + None => ( + load_layout_from_resource(name), + DataSource::Resource(name.into()), + ), + }; + + // FIXME: attempt at each step of fallback let layout = layout.and_then( |layout| layout.build().map_err(LoadError::BadKeyMap) ); - (layout, source) + (layout, source, failed_attempt) } fn load_layout_with_fallback( name: &str ) -> ::layout::Layout { - let (layout, source) = load_layout(name); - let (layout, source) = match (layout, source) { + let (layout, source, attempt) = load_layout(name); + + if let Some((e, source)) = attempt { + eprintln!( + "Failed to load layout from {}: {}, trying builtin", + source, e + ); + }; + + let (layout, source, attempt) = match (layout, source) { (Err(e), source) => { eprintln!( "Failed to load layout from {}: {}, using fallback", @@ -131,24 +155,14 @@ fn load_layout_with_fallback( ); load_layout(FALLBACK_LAYOUT_NAME) }, - res => res, + (res, source) => (res, source, None), }; - let (layout, source) = match (layout, source) { - (Err(e), source) => { - eprintln!( - "Failed to load fallback layout from {}: {}, using hardcoded", - source, e - ); - ( - load_layout_from_resource(FALLBACK_LAYOUT_NAME) - .and_then( - |layout| layout.build().map_err(LoadError::BadKeyMap) - ), - DataSource::Resource(FALLBACK_LAYOUT_NAME.into()), - ) - }, - res => res, + if let Some((e, source)) = attempt { + eprintln!( + "Failed to load layout from {}: {}, trying builtin", + source, e + ); }; match (layout, source) {