use {
crate::{
engine::{Engine, EngineBuilder, EngineType, EngineTypes},
ffi::Library,
program::Program,
ParseError,
},
std::{ffi::CString, path::Path},
};
#[derive(thiserror::Error, Debug)]
pub enum LibraryError {
#[error("Failed to load library")]
FailedToLoadLibrary(#[from] libloading::Error),
#[error("Engine not found")]
EngineNotFound,
#[error("CMAJOR_LIB_PATH environment variable not set")]
EnvVarNotSet,
}
pub struct Cmajor {
library: Library,
}
impl Default for Cmajor {
fn default() -> Self {
Self::new()
}
}
impl Cmajor {
#[cfg(feature = "static")]
pub fn new() -> Self {
Self {
library: Library::new(),
}
}
#[cfg(not(feature = "static"))]
pub fn new() -> Self {
Self::new_from_env().unwrap()
}
pub fn new_from_path(path_to_library: impl AsRef<Path>) -> Result<Self, LibraryError> {
let library = Library::load(path_to_library)?;
Ok(Self { library })
}
pub fn new_from_env() -> Result<Self, LibraryError> {
let _ = dotenvy::dotenv();
std::env::var("CMAJOR_LIB_PATH")
.map_err(|_| LibraryError::EnvVarNotSet)
.and_then(Self::new_from_path)
}
pub fn version(&self) -> &str {
self.library.version().to_str().unwrap_or_default()
}
fn create_program(&self) -> Program {
Program {
inner: self.library.create_program(),
}
}
pub fn parse(&self, cmajor_program: impl AsRef<str>) -> Result<Program, ParseError> {
let mut program = self.create_program();
program.parse(cmajor_program)?;
Ok(program)
}
pub fn engine_types(&self) -> impl Iterator<Item = EngineType> + '_ {
EngineTypes::new(self.library.engine_types())
}
pub fn create_default_engine(&self) -> EngineBuilder {
self.create_engine(EngineType::default_engine_type())
}
pub fn create_engine(&self, engine_type: EngineType) -> EngineBuilder {
let engine_type = CString::new(engine_type.to_str())
.expect("engine type should not contain a null character");
let engine_factory = self
.library
.create_engine_factory(engine_type.as_c_str())
.expect("engine factory not found");
let engine = engine_factory.create_engine(None);
EngineBuilder {
sample_rate: 0.0,
engine: Engine::new(engine),
}
}
}