layouts: Test fallback order
This commit is contained in:
		
							
								
								
									
										50
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/data.rs
									
									
									
									
									
								
							@ -40,7 +40,7 @@ pub mod c {
 | 
				
			|||||||
            .expect("Bad layout name")
 | 
					            .expect("Bad layout name")
 | 
				
			||||||
            .expect("Empty layout name");
 | 
					            .expect("Empty layout name");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let layout = load_layout_with_fallback(name);
 | 
					        let layout = build_layout_with_fallback(name);
 | 
				
			||||||
        Box::into_raw(Box::new(layout))
 | 
					        Box::into_raw(Box::new(layout))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -76,6 +76,7 @@ pub fn load_layout_from_resource(
 | 
				
			|||||||
                .map_err(|e| LoadError::BadResource(e))
 | 
					                .map_err(|e| LoadError::BadResource(e))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
enum DataSource {
 | 
					enum DataSource {
 | 
				
			||||||
    File(PathBuf),
 | 
					    File(PathBuf),
 | 
				
			||||||
    Resource(String),
 | 
					    Resource(String),
 | 
				
			||||||
@ -93,16 +94,14 @@ impl fmt::Display for DataSource {
 | 
				
			|||||||
/// Tries to load the layout from the first place where it's present.
 | 
					/// Tries to load the layout from the first place where it's present.
 | 
				
			||||||
/// 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,
 | 
				
			||||||
 | 
					    keyboards_path: Option<PathBuf>,
 | 
				
			||||||
) -> (
 | 
					) -> (
 | 
				
			||||||
    Result<::layout::Layout, LoadError>, // last attempted
 | 
					    Result<Layout, LoadError>, // last attempted
 | 
				
			||||||
    DataSource, // last attempt source
 | 
					    DataSource, // last attempt source
 | 
				
			||||||
    Option<(LoadError, DataSource)>, // first attempt source
 | 
					    Option<(LoadError, DataSource)>, // first attempt source
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
 | 
					    let path = keyboards_path.map(|path| path.join(name).with_extension("yaml"));
 | 
				
			||||||
        .map(PathBuf::from)
 | 
					 | 
				
			||||||
        .or_else(|| xdg::data_path("squeekboard/keyboards"))
 | 
					 | 
				
			||||||
        .map(|path| path.join(name).with_extension("yaml"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let layout = match path {
 | 
					    let layout = match path {
 | 
				
			||||||
        Some(path) => Some((
 | 
					        Some(path) => Some((
 | 
				
			||||||
@ -126,6 +125,19 @@ fn load_layout(
 | 
				
			|||||||
            DataSource::Resource(name.into()),
 | 
					            DataSource::Resource(name.into()),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (layout, source, failed_attempt)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn build_layout(
 | 
				
			||||||
 | 
					    name: &str,
 | 
				
			||||||
 | 
					    keyboards_path: Option<PathBuf>,
 | 
				
			||||||
 | 
					) -> (
 | 
				
			||||||
 | 
					    Result<::layout::Layout, LoadError>, // last attempted
 | 
				
			||||||
 | 
					    DataSource, // last attempt source
 | 
				
			||||||
 | 
					    Option<(LoadError, DataSource)>, // first attempt source
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    let (layout, source, failed_attempt) = load_layout(name, keyboards_path);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // FIXME: attempt at each step of fallback
 | 
					    // FIXME: attempt at each step of fallback
 | 
				
			||||||
    let layout = layout.and_then(
 | 
					    let layout = layout.and_then(
 | 
				
			||||||
@ -135,10 +147,14 @@ fn load_layout(
 | 
				
			|||||||
    (layout, source, failed_attempt)
 | 
					    (layout, source, failed_attempt)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn load_layout_with_fallback(
 | 
					fn build_layout_with_fallback(
 | 
				
			||||||
    name: &str
 | 
					    name: &str
 | 
				
			||||||
) -> ::layout::Layout {
 | 
					) -> ::layout::Layout {
 | 
				
			||||||
    let (layout, source, attempt) = load_layout(name);
 | 
					    let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
 | 
				
			||||||
 | 
					        .map(PathBuf::from)
 | 
				
			||||||
 | 
					        .or_else(|| xdg::data_path("squeekboard/keyboards"));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let (layout, source, attempt) = build_layout(name, path.clone());
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if let Some((e, source)) = attempt {
 | 
					    if let Some((e, source)) = attempt {
 | 
				
			||||||
        eprintln!(
 | 
					        eprintln!(
 | 
				
			||||||
@ -153,7 +169,7 @@ fn load_layout_with_fallback(
 | 
				
			|||||||
                "Failed to load layout from {}: {}, using fallback",
 | 
					                "Failed to load layout from {}: {}, using fallback",
 | 
				
			||||||
                source, e
 | 
					                source, e
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            load_layout(FALLBACK_LAYOUT_NAME)
 | 
					            build_layout(FALLBACK_LAYOUT_NAME, path)
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        (res, source) => (res, source, None),
 | 
					        (res, source) => (res, source, None),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@ -621,6 +637,20 @@ mod tests {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    /// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn fallbacks_order() {
 | 
				
			||||||
 | 
					        let (layout, source, _failure) = load_layout(
 | 
				
			||||||
 | 
					            "nb",
 | 
				
			||||||
 | 
					            Some(PathBuf::from("tests"))
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            source,
 | 
				
			||||||
 | 
					            load_layout("nb", None).1
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn unicode_keysym() {
 | 
					    fn unicode_keysym() {
 | 
				
			||||||
        let keysym = xkb::keysym_from_name(
 | 
					        let keysym = xkb::keysym_from_name(
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user