use std::path::PathBuf;
use baracuda_types::{CudaStatus, CudaVersion};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum LoaderError {
#[error("could not load {library}: tried {candidates:?} across {search_paths} path(s)")]
LibraryNotFound {
library: &'static str,
candidates: Vec<&'static str>,
search_paths: usize,
},
#[error("library '{library}' is missing symbol '{symbol}'")]
SymbolNotFound {
library: &'static str,
symbol: &'static str,
},
#[error("symbol '{symbol}' requires {required} but baracuda's driver loader sees {installed}")]
VersionTooOld {
symbol: &'static str,
required: CudaVersion,
installed: CudaVersion,
},
#[error("{0}")]
Libloading(#[from] libloading::Error),
#[error("baracuda does not support {platform}; NVIDIA driver is only available on Linux and Windows")]
UnsupportedPlatform { platform: &'static str },
}
impl LoaderError {
pub fn library_not_found(library: &'static str, candidates: &[&'static str]) -> Self {
Self::LibraryNotFound {
library,
candidates: candidates.to_vec(),
search_paths: 0,
}
}
pub fn library_not_found_with_search(
library: &'static str,
candidates: &[&'static str],
search_path_count: usize,
) -> Self {
Self::LibraryNotFound {
library,
candidates: candidates.to_vec(),
search_paths: search_path_count,
}
}
}
#[derive(Debug, Error)]
pub enum Error<S>
where
S: CudaStatus + Send + Sync + 'static,
{
#[error("{} returned {} ({}): {}", .status.library(), .status.name(), .status.code(), .status.description())]
Status { status: S },
#[error(transparent)]
Loader(#[from] LoaderError),
#[error("{api} requires {since}; install a newer driver to use it")]
FeatureNotSupported {
api: &'static str,
since: CudaVersion,
},
}
impl<S> Error<S>
where
S: CudaStatus + Send + Sync + 'static,
{
pub fn check(status: S) -> Result<(), Self> {
if status.is_success() {
Ok(())
} else {
Err(Self::Status { status })
}
}
}
#[derive(Debug, Error)]
pub enum BaracudaError {
#[error("{library} returned {name} ({code}): {description}")]
Status {
library: &'static str,
name: &'static str,
description: &'static str,
code: i32,
},
#[error(transparent)]
Loader(#[from] LoaderError),
#[error("{api} requires {since}; install a newer driver to use it")]
FeatureNotSupported {
api: &'static str,
since: CudaVersion,
},
#[error("{context}")]
Context { context: &'static str },
}
impl<S> From<Error<S>> for BaracudaError
where
S: CudaStatus + Send + Sync + 'static,
{
fn from(err: Error<S>) -> Self {
match err {
Error::Status { status } => BaracudaError::Status {
library: status.library(),
name: status.name(),
description: status.description(),
code: status.code(),
},
Error::Loader(l) => BaracudaError::Loader(l),
Error::FeatureNotSupported { api, since } => {
BaracudaError::FeatureNotSupported { api, since }
}
}
}
}
#[allow(dead_code)]
pub(crate) type PathList = Vec<PathBuf>;