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.
This commit is contained in:
Dorota Czaplejewicz
2019-09-28 21:14:14 +00:00
parent 5ef687a722
commit b6d25da7c2

View File

@ -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) {