pub use crate::timing::{
BenchReport as RunnerReport, BenchSample, BenchSpec, BenchSummary, HarnessTimelineSpan,
SemanticPhase, TimingError as RunnerError,
};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::path::PathBuf;
#[derive(Debug, thiserror::Error)]
pub enum BenchError {
#[error("benchmark runner error: {0}")]
Runner(#[from] crate::timing::TimingError),
#[error(
"unknown benchmark function: '{0}'. Available benchmarks: {1:?}\n\nEnsure the function is:\n 1. Annotated with #[benchmark]\n 2. Public (pub fn)\n 3. Takes no parameters and returns ()"
)]
UnknownFunction(String, Vec<String>),
#[error("benchmark execution failed: {0}")]
Execution(String),
#[error("I/O error: {0}. Check file paths and permissions")]
Io(#[from] std::io::Error),
#[error("serialization error: {0}. Check JSON validity or output serializability")]
Serialization(#[from] serde_json::Error),
#[error("configuration error: {0}. Check mobench.toml or CLI flags")]
Config(String),
#[error("build error: {0}")]
Build(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Target {
Android,
Ios,
Both,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum FfiBackend {
#[default]
Uniffi,
NativeCAbi,
#[serde(rename = "boltffi", alias = "bolt-ffi")]
BoltFfi,
}
impl FfiBackend {
pub fn as_str(&self) -> &'static str {
match self {
FfiBackend::Uniffi => "uniffi",
FfiBackend::NativeCAbi => "native-c-abi",
FfiBackend::BoltFfi => "boltffi",
}
}
pub fn uses_uniffi(&self) -> bool {
matches!(self, FfiBackend::Uniffi)
}
pub fn uses_boltffi(&self) -> bool {
matches!(self, FfiBackend::BoltFfi)
}
pub fn uses_native_c_abi(&self) -> bool {
matches!(self, FfiBackend::NativeCAbi)
}
}
impl fmt::Display for FfiBackend {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl Target {
pub fn as_str(&self) -> &'static str {
match self {
Target::Android => "android",
Target::Ios => "ios",
Target::Both => "both",
}
}
}
#[derive(Debug, Clone)]
pub struct InitConfig {
pub target: Target,
pub project_name: String,
pub output_dir: PathBuf,
pub generate_examples: bool,
}
#[derive(Debug, Clone)]
pub struct BuildConfig {
pub target: Target,
pub profile: BuildProfile,
pub incremental: bool,
pub android_abis: Option<Vec<String>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BuildProfile {
Debug,
Release,
}
impl BuildProfile {
pub fn as_str(&self) -> &'static str {
match self {
BuildProfile::Debug => "debug",
BuildProfile::Release => "release",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NativeLibraryArtifact {
pub abi: String,
pub library_name: String,
pub unstripped_path: PathBuf,
pub packaged_path: PathBuf,
}
#[derive(Debug, Clone)]
pub struct BuildResult {
pub platform: Target,
pub app_path: PathBuf,
pub test_suite_path: Option<PathBuf>,
pub native_libraries: Vec<NativeLibraryArtifact>,
}