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:
66
src/data.rs
66
src/data.rs
@ -94,36 +94,60 @@ impl fmt::Display for DataSource {
|
|||||||
/// If the layout exists, but is broken, fallback is activated.
|
/// If the layout exists, but is broken, fallback is activated.
|
||||||
fn load_layout(
|
fn load_layout(
|
||||||
name: &str
|
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")
|
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.or_else(|| xdg::data_path("squeekboard/keyboards"))
|
.or_else(|| xdg::data_path("squeekboard/keyboards"))
|
||||||
.map(|path| path.join(name).with_extension("yaml"));
|
.map(|path| path.join(name).with_extension("yaml"));
|
||||||
|
|
||||||
let (layout, source) = match path {
|
let layout = match path {
|
||||||
Some(path) => {(
|
Some(path) => Some((
|
||||||
Layout::from_yaml_stream(path.clone())
|
Layout::from_yaml_stream(path.clone())
|
||||||
.map_err(|e| LoadError::BadData(e)),
|
.map_err(LoadError::BadData),
|
||||||
DataSource::File(path)
|
DataSource::File(path),
|
||||||
)},
|
)),
|
||||||
None => {(
|
None => None, // No env var, not an error
|
||||||
load_layout_from_resource(name),
|
|
||||||
DataSource::Resource(name.into())
|
|
||||||
)},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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(
|
let layout = layout.and_then(
|
||||||
|layout| layout.build().map_err(LoadError::BadKeyMap)
|
|layout| layout.build().map_err(LoadError::BadKeyMap)
|
||||||
);
|
);
|
||||||
|
|
||||||
(layout, source)
|
(layout, source, failed_attempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_layout_with_fallback(
|
fn load_layout_with_fallback(
|
||||||
name: &str
|
name: &str
|
||||||
) -> ::layout::Layout {
|
) -> ::layout::Layout {
|
||||||
let (layout, source) = load_layout(name);
|
let (layout, source, attempt) = load_layout(name);
|
||||||
let (layout, source) = match (layout, source) {
|
|
||||||
|
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) => {
|
(Err(e), source) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to load layout from {}: {}, using fallback",
|
"Failed to load layout from {}: {}, using fallback",
|
||||||
@ -131,24 +155,14 @@ fn load_layout_with_fallback(
|
|||||||
);
|
);
|
||||||
load_layout(FALLBACK_LAYOUT_NAME)
|
load_layout(FALLBACK_LAYOUT_NAME)
|
||||||
},
|
},
|
||||||
res => res,
|
(res, source) => (res, source, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (layout, source) = match (layout, source) {
|
if let Some((e, source)) = attempt {
|
||||||
(Err(e), source) => {
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to load fallback layout from {}: {}, using hardcoded",
|
"Failed to load layout from {}: {}, trying builtin",
|
||||||
source, e
|
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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match (layout, source) {
|
match (layout, source) {
|
||||||
|
|||||||
Reference in New Issue
Block a user