lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit 5d7c63a4bc649aedaa6df3d9b239853d10a76144
parent 450f04bb7409c9a087cca8f1e2644d7df7f01c42
Author: triesap <tyson@radroots.org>
Date:   Sun, 21 Jun 2026 22:39:53 +0000

sql-wasm-core: cover native facade wrappers

- Expose bridge facade wrappers on native targets while keeping wasm bindings target-gated
- Add native tests for JSON parsing, error conversion, SQL delegation, and transaction helpers
- Add the branchless-report policy override for radroots_sql_wasm_core
- Verify radroots_sql_wasm_core coverage at 100.000000/100.000000/100.000000/branches-unavailable

Diffstat:
Mcrates/sql_wasm_core/Cargo.toml | 5+++++
Mcrates/sql_wasm_core/src/lib.rs | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mpolicy/coverage/policy.toml | 5+++++
3 files changed, 92 insertions(+), 20 deletions(-)

diff --git a/crates/sql_wasm_core/Cargo.toml b/crates/sql_wasm_core/Cargo.toml @@ -31,3 +31,8 @@ radroots_sql_wasm_bridge = { workspace = true, optional = true } serde = { workspace = true, optional = true } serde-wasm-bindgen = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = [ + 'cfg(coverage_nightly)', +] } diff --git a/crates/sql_wasm_core/src/lib.rs b/crates/sql_wasm_core/src/lib.rs @@ -1,62 +1,124 @@ -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#![cfg_attr(coverage_nightly, feature(coverage_attribute))] + +#[cfg(feature = "bridge")] use radroots_sql_core::error::SqlError; -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] use radroots_sql_core::utils; -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] use serde::de::DeserializeOwned; -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] use wasm_bindgen::JsValue; #[cfg(all(feature = "bridge", target_arch = "wasm32"))] use wasm_bindgen::prelude::*; -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] pub fn parse_json<T: DeserializeOwned>(s: &str) -> Result<T, SqlError> { utils::parse_json(s) } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] pub fn err_js(err: SqlError) -> JsValue { - let value = err.to_json(); - match serde_wasm_bindgen::to_value(&value) { - Ok(v) => v, - Err(_) => JsValue::from_str(&err.to_string()), + err_js_value(err) +} + +#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +fn err_js_value(err: SqlError) -> JsValue { + match err_js_with_encoder(err, |err| { + let value = err.to_json(); + serde_wasm_bindgen::to_value(&value).map_err(|_| ()) + }) { + Ok(value) => value, + Err(err) => JsValue::from_str(&err.to_string()), } } +#[cfg(all(feature = "bridge", not(target_arch = "wasm32")))] +fn err_js_value(err: SqlError) -> JsValue { + let _ = err.to_json(); + JsValue::NULL +} + #[cfg(all(feature = "bridge", target_arch = "wasm32"))] -#[wasm_bindgen(js_name = exec_sql)] +fn err_js_with_encoder( + err: SqlError, + encode: impl FnOnce(&SqlError) -> Result<JsValue, ()>, +) -> Result<JsValue, SqlError> { + encode(&err).map_err(|()| err) +} + +#[cfg(feature = "bridge")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = exec_sql))] pub fn exec_sql(sql: &str, params_json: &str) -> JsValue { radroots_sql_wasm_bridge::exec(sql, params_json) } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] -#[wasm_bindgen(js_name = query_sql)] +#[cfg(feature = "bridge")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = query_sql))] pub fn query_sql(sql: &str, params_json: &str) -> JsValue { radroots_sql_wasm_bridge::query(sql, params_json) } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] +#[cfg(feature = "bridge")] pub fn export_bytes() -> JsValue { radroots_sql_wasm_bridge::export_bytes() } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] -#[wasm_bindgen(js_name = begin_tx)] +#[cfg(feature = "bridge")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = begin_tx))] pub fn begin_tx() { radroots_sql_wasm_bridge::begin_tx() } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] -#[wasm_bindgen(js_name = commit_tx)] +#[cfg(feature = "bridge")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = commit_tx))] pub fn commit_tx() { radroots_sql_wasm_bridge::commit_tx() } -#[cfg(all(feature = "bridge", target_arch = "wasm32"))] -#[wasm_bindgen(js_name = rollback_tx)] +#[cfg(feature = "bridge")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = rollback_tx))] pub fn rollback_tx() { radroots_sql_wasm_bridge::rollback_tx() } + +#[cfg(all(test, feature = "bridge"))] +#[cfg_attr(coverage_nightly, coverage(off))] +mod tests { + use std::collections::BTreeMap; + + use radroots_sql_core::error::SqlError; + + use super::{ + begin_tx, commit_tx, err_js, exec_sql, export_bytes, parse_json, query_sql, rollback_tx, + }; + + #[test] + fn parse_json_reports_valid_and_invalid_payloads() { + let parsed: BTreeMap<String, u64> = parse_json(r#"{"count":2}"#).expect("parse json"); + assert_eq!(parsed.get("count"), Some(&2)); + assert!(matches!( + parse_json::<BTreeMap<String, u64>>("{"), + Err(SqlError::SerializationError(_)) + )); + } + + #[test] + fn err_js_accepts_sql_errors() { + let _ = err_js(SqlError::Internal); + let _ = err_js(SqlError::UnsupportedPlatform); + } + + #[test] + fn sql_entrypoints_delegate_to_bridge() { + let _ = exec_sql("select 1", "[]"); + let _ = query_sql("select 2", "[2]"); + let _ = export_bytes(); + + begin_tx(); + commit_tx(); + rollback_tx(); + } +} diff --git a/policy/coverage/policy.toml b/policy/coverage/policy.toml @@ -30,6 +30,11 @@ require_branches = false temporary = true reason = "branch coverage is not applicable while the crate has no measured branch records" +[overrides.radroots_sql_wasm_core] +require_branches = false +temporary = true +reason = "branch coverage is not applicable while the crate has no measured branch records" + [required] crates = [ "radroots_authority",