use serde::{Deserialize, Serialize};
#[cfg(feature = "bindgen")]
use wasm_bindgen::prelude::*;
pub const ABI_VERSION: u32 = 2;
#[cfg_attr(feature = "bindgen", wasm_bindgen(js_name = abiVersion))]
pub fn abi_version() -> u32 {
ABI_VERSION
}
#[cfg(feature = "bindgen")]
#[wasm_bindgen(js_name = initPanicHook)]
pub fn init_panic_hook() {
console_error_panic_hook::set_once();
}
pub fn normalize_range(start: usize, end: usize) -> Result<(usize, usize), FcError> {
if end < start {
return Err(FcError::InvalidInput {
message: format!("range end ({end}) precedes start ({start})"),
});
}
Ok((start, end))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn abi_version_matches_the_exported_constant() {
assert_eq!(abi_version(), ABI_VERSION);
}
#[test]
fn normalize_range_accepts_forward_and_empty_ranges() {
assert_eq!(normalize_range(0, 5).unwrap(), (0, 5));
assert_eq!(normalize_range(3, 3).unwrap(), (3, 3));
}
#[test]
fn normalize_range_rejects_backwards_ranges() {
let err = normalize_range(5, 2).unwrap_err();
assert_eq!(err.kind(), "invalidInput");
assert!(err.message().contains("precedes"));
}
#[test]
fn error_kinds_are_stable() {
assert_eq!(FcError::InvalidInput { message: String::new() }.kind(), "invalidInput");
assert_eq!(FcError::Unsupported { message: String::new() }.kind(), "unsupported");
assert_eq!(FcError::OutOfBounds { message: String::new() }.kind(), "outOfBounds");
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum FcError {
InvalidInput { message: String },
Unsupported { message: String },
OutOfBounds { message: String },
}
impl FcError {
pub fn kind(&self) -> &'static str {
match self {
FcError::InvalidInput { .. } => "invalidInput",
FcError::Unsupported { .. } => "unsupported",
FcError::OutOfBounds { .. } => "outOfBounds",
}
}
pub fn message(&self) -> &str {
match self {
FcError::InvalidInput { message }
| FcError::Unsupported { message }
| FcError::OutOfBounds { message } => message,
}
}
}
#[cfg(feature = "bindgen")]
impl From<FcError> for JsValue {
fn from(err: FcError) -> Self {
let mut message = String::from("fc:");
message.push_str(err.kind());
message.push(':');
message.push_str(err.message());
JsValue::from_str(&message)
}
}