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