Skip to main content

mobench_sdk/
types.rs

1//! Core types for mobench-sdk.
2//!
3//! This module defines the fundamental types used throughout the SDK:
4//!
5//! - [`BenchError`] - Error types for benchmark and build operations
6//! - [`Target`] - Platform selection (Android, iOS, or both)
7//! - [`BuildConfig`] / [`BuildProfile`] - Build configuration options
8//! - [`BuildResult`] - Output from build operations
9//! - [`InitConfig`] - Project initialization settings
10//!
11//! ## Re-exports from timing module
12//!
13//! For convenience, this module also re-exports types from [`crate::timing`]:
14//!
15//! - [`BenchSpec`] - Benchmark specification (name, iterations, warmup)
16//! - [`BenchSample`] - Single timing measurement
17//! - [`RunnerReport`] - Complete benchmark results
18
19// Re-export timing types for convenience
20pub use crate::timing::{
21    BenchReport as RunnerReport, BenchSample, BenchSpec, BenchSummary, HarnessTimelineSpan,
22    SemanticPhase, TimingError as RunnerError,
23};
24
25use std::path::PathBuf;
26
27/// Error types for mobench-sdk operations.
28///
29/// This enum covers all error conditions that can occur during
30/// benchmark registration, execution, and mobile app building.
31///
32/// # Example
33///
34/// ```ignore
35/// use mobench_sdk::{run_benchmark, BenchSpec, BenchError};
36///
37/// let spec = BenchSpec {
38///     name: "nonexistent".to_string(),
39///     iterations: 10,
40///     warmup: 1,
41/// };
42///
43/// match run_benchmark(spec) {
44///     Ok(report) => println!("Success!"),
45///     Err(BenchError::UnknownFunction(name)) => {
46///         eprintln!("Benchmark '{}' not found", name);
47///     }
48///     Err(e) => eprintln!("Other error: {}", e),
49/// }
50/// ```
51#[derive(Debug, thiserror::Error)]
52pub enum BenchError {
53    /// Error from the underlying benchmark runner.
54    ///
55    /// This wraps errors from [`crate::timing::TimingError`], such as
56    /// zero iterations or execution failures.
57    #[error("benchmark runner error: {0}")]
58    Runner(#[from] crate::timing::TimingError),
59
60    /// The requested benchmark function was not found in the registry.
61    ///
62    /// This occurs when calling [`run_benchmark`](crate::run_benchmark) with
63    /// a function name that hasn't been registered via `#[benchmark]`.
64    ///
65    /// The error includes a list of available benchmarks to help diagnose the issue.
66    #[error(
67        "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 ()"
68    )]
69    UnknownFunction(String, Vec<String>),
70
71    /// An error occurred during benchmark execution.
72    ///
73    /// This is a catch-all for execution-time errors that don't fit
74    /// other categories.
75    #[error("benchmark execution failed: {0}")]
76    Execution(String),
77
78    /// An I/O error occurred.
79    ///
80    /// Common causes include missing files, permission issues, or
81    /// disk space problems during build operations.
82    #[error("I/O error: {0}. Check file paths and permissions")]
83    Io(#[from] std::io::Error),
84
85    /// JSON serialization or deserialization failed.
86    ///
87    /// This can occur when reading/writing benchmark specifications
88    /// or configuration files.
89    #[error("serialization error: {0}. Check JSON validity or output serializability")]
90    Serialization(#[from] serde_json::Error),
91
92    /// A configuration error occurred.
93    ///
94    /// This indicates invalid or missing configuration, such as
95    /// malformed TOML files or missing required fields.
96    #[error("configuration error: {0}. Check mobench.toml or CLI flags")]
97    Config(String),
98
99    /// A build error occurred.
100    ///
101    /// This covers failures during mobile app building, including:
102    /// - Missing build tools (cargo-ndk, xcodebuild, etc.)
103    /// - Compilation errors
104    /// - Code signing failures
105    /// - Missing dependencies
106    #[error("build error: {0}")]
107    Build(String),
108}
109
110/// Target platform for benchmarks.
111///
112/// Specifies which mobile platform(s) to build for or run benchmarks on.
113///
114/// # Example
115///
116/// ```
117/// use mobench_sdk::Target;
118///
119/// let target = Target::Android;
120/// assert_eq!(target.as_str(), "android");
121///
122/// let both = Target::Both;
123/// assert_eq!(both.as_str(), "both");
124/// ```
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub enum Target {
127    /// Android platform (APK with native .so libraries).
128    Android,
129    /// iOS platform (xcframework with static libraries).
130    Ios,
131    /// Both Android and iOS platforms.
132    Both,
133}
134
135impl Target {
136    /// Returns the string representation of the target.
137    ///
138    /// # Returns
139    ///
140    /// - `"android"` for [`Target::Android`]
141    /// - `"ios"` for [`Target::Ios`]
142    /// - `"both"` for [`Target::Both`]
143    pub fn as_str(&self) -> &'static str {
144        match self {
145            Target::Android => "android",
146            Target::Ios => "ios",
147            Target::Both => "both",
148        }
149    }
150}
151
152/// Configuration for initializing a new benchmark project.
153///
154/// Used by the `cargo mobench init` command to generate project scaffolding.
155///
156/// # Example
157///
158/// ```
159/// use mobench_sdk::{InitConfig, Target};
160/// use std::path::PathBuf;
161///
162/// let config = InitConfig {
163///     target: Target::Android,
164///     project_name: "my-benchmarks".to_string(),
165///     output_dir: PathBuf::from("./bench-mobile"),
166///     generate_examples: true,
167/// };
168/// ```
169#[derive(Debug, Clone)]
170pub struct InitConfig {
171    /// Target platform(s) to initialize for.
172    pub target: Target,
173    /// Name of the benchmark project/crate.
174    pub project_name: String,
175    /// Output directory for generated files.
176    pub output_dir: PathBuf,
177    /// Whether to generate example benchmark functions.
178    pub generate_examples: bool,
179}
180
181/// Configuration for building mobile apps.
182///
183/// Controls the build process including target platform, optimization level,
184/// and caching behavior.
185///
186/// # Example
187///
188/// ```
189/// use mobench_sdk::{BuildConfig, BuildProfile, Target};
190///
191/// // Release build for Android
192/// let config = BuildConfig {
193///     target: Target::Android,
194///     profile: BuildProfile::Release,
195///     incremental: true,
196///     android_abis: None,
197/// };
198///
199/// // Debug build for iOS
200/// let ios_config = BuildConfig {
201///     target: Target::Ios,
202///     profile: BuildProfile::Debug,
203///     incremental: false,  // Force rebuild
204///     android_abis: None,
205/// };
206/// ```
207#[derive(Debug, Clone)]
208pub struct BuildConfig {
209    /// Target platform to build for.
210    pub target: Target,
211    /// Build profile (debug or release).
212    pub profile: BuildProfile,
213    /// If `true`, skip rebuilding if artifacts already exist.
214    pub incremental: bool,
215    /// Optional Android ABIs to build/package. Defaults to `["arm64-v8a"]`.
216    pub android_abis: Option<Vec<String>>,
217}
218
219/// Build profile controlling optimization and debug info.
220///
221/// Similar to Cargo's `--release` flag, this controls whether the build
222/// is optimized for debugging or performance.
223///
224/// # Example
225///
226/// ```
227/// use mobench_sdk::BuildProfile;
228///
229/// let debug = BuildProfile::Debug;
230/// assert_eq!(debug.as_str(), "debug");
231///
232/// let release = BuildProfile::Release;
233/// assert_eq!(release.as_str(), "release");
234/// ```
235#[derive(Debug, Clone, Copy, PartialEq, Eq)]
236pub enum BuildProfile {
237    /// Debug build with debug symbols and no optimizations.
238    ///
239    /// Faster compilation but slower runtime. Useful for development
240    /// and troubleshooting.
241    Debug,
242    /// Release build with optimizations enabled.
243    ///
244    /// Slower compilation but faster runtime. Use this for actual
245    /// benchmark measurements.
246    Release,
247}
248
249impl BuildProfile {
250    /// Returns the string representation of the profile.
251    ///
252    /// # Returns
253    ///
254    /// - `"debug"` for [`BuildProfile::Debug`]
255    /// - `"release"` for [`BuildProfile::Release`]
256    pub fn as_str(&self) -> &'static str {
257        match self {
258            BuildProfile::Debug => "debug",
259            BuildProfile::Release => "release",
260        }
261    }
262}
263
264/// Result of a successful build operation.
265///
266/// Contains paths to the built artifacts, which can be used for
267/// deployment to BrowserStack or local testing.
268///
269/// # Example
270///
271/// ```ignore
272/// use mobench_sdk::builders::AndroidBuilder;
273///
274/// let result = builder.build(&config)?;
275///
276/// println!("App built at: {:?}", result.app_path);
277/// if let Some(test_suite) = result.test_suite_path {
278///     println!("Test suite at: {:?}", test_suite);
279/// }
280/// ```
281#[derive(Debug, Clone, PartialEq, Eq)]
282pub struct NativeLibraryArtifact {
283    /// ABI name used in Android packaging, for example `arm64-v8a`.
284    pub abi: String,
285    /// Shared library filename, for example `libsample_fns.so`.
286    pub library_name: String,
287    /// Path to the unstripped library produced by Cargo.
288    pub unstripped_path: PathBuf,
289    /// Path to the packaged copy under `jniLibs/`.
290    pub packaged_path: PathBuf,
291}
292
293#[derive(Debug, Clone)]
294pub struct BuildResult {
295    /// Platform that was built.
296    pub platform: Target,
297    /// Path to the main app artifact.
298    ///
299    /// - Android: Path to the APK file
300    /// - iOS: Path to the xcframework directory
301    pub app_path: PathBuf,
302    /// Path to the test suite artifact, if applicable.
303    ///
304    /// - Android: Path to the androidTest APK (for Espresso)
305    /// - iOS: Path to the XCUITest runner zip
306    pub test_suite_path: Option<PathBuf>,
307    /// Native libraries associated with this build, when applicable.
308    pub native_libraries: Vec<NativeLibraryArtifact>,
309}