use impeller_hal::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BackendPreference {
#[default]
Auto,
Vulkan,
Gles,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Backend {
Vulkan,
Gles,
}
impl Backend {
pub fn name(self) -> &'static str {
match self {
Self::Vulkan => "vulkan",
Self::Gles => "gles",
}
}
}
impl std::fmt::Display for Backend {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name())
}
}
pub(crate) fn no_backend(attempts: Vec<(Backend, Error)>) -> Error {
if attempts.is_empty() {
return Error::Unsupported("no rendering backend was compiled in");
}
let detail = attempts
.iter()
.map(|(backend, error)| format!(" {backend}: {error}"))
.collect::<Vec<_>>()
.join("\n");
Error::Backend {
backend: "impeller",
detail: format!("no usable rendering backend:\n{detail}"),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_failure_names_every_candidate_and_its_reason() {
let error = no_backend(vec![
(Backend::Vulkan, Error::Unsupported("no device")),
(
Backend::Gles,
Error::Backend {
backend: "gles",
detail: "libEGL missing".into(),
},
),
]);
let text = error.to_string();
assert!(text.contains("vulkan"), "{text}");
assert!(text.contains("no device"), "{text}");
assert!(text.contains("gles"), "{text}");
assert!(text.contains("libEGL missing"), "{text}");
}
#[test]
fn a_build_with_no_backends_says_so_rather_than_blaming_the_machine() {
let error = no_backend(Vec::new());
assert!(error.to_string().contains("compiled in"));
}
#[test]
fn auto_is_the_default_preference() {
assert_eq!(BackendPreference::default(), BackendPreference::Auto);
}
}