From: Ian Jackson Date: Mon, 12 Oct 2020 00:14:35 +0000 (+0100) Subject: bindings X-Git-Tag: otter-0.2.0~665 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=763d0173f9b1ac891a649a6dd5a62310c624c25d;p=otter.git bindings Signed-off-by: Ian Jackson --- diff --git a/Cargo.lock.example b/Cargo.lock.example index 79fdb2fe..e7a7636a 100644 --- a/Cargo.lock.example +++ b/Cargo.lock.example @@ -1015,6 +1015,7 @@ dependencies = [ "fehler", "js-sys", "otter-zcoord", + "thiserror", "wasm-bindgen", "wee_alloc", ] diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 58065953..cffff750 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -17,5 +17,6 @@ otter-zcoord = { path = "../zcoord" } wasm-bindgen = "0.2" js-sys = "0.3" fehler = "1" +thiserror = "1" wee_alloc = "0.4" #wee_alloc = { version = "0.4.5", optional = true } diff --git a/wasm/wasm.rs b/wasm/wasm.rs index 1bff0028..7bea8ecf 100644 --- a/wasm/wasm.rs +++ b/wasm/wasm.rs @@ -1,13 +1,15 @@ -use wasm_bindgen::prelude::*; -use fehler::throws; use std::fmt::Display; +use fehler::throws; use js_sys::JsString; +use thiserror::Error; +use wasm_bindgen::prelude::*; -use zcoord::ZCoord; +use zcoord::{ZCoord,Mutable}; -#[wasm_bindgen] -pub struct ZCoordIterator (zcoord::Mutable); +#[derive(Error,Clone,Copy,Debug,Eq,PartialEq)] +#[error("packed Z coordinate wrong JS type (not a string)")] +pub struct JsZCoordTypeError; trait WasmError { fn e(self) -> JsValue; @@ -28,26 +30,47 @@ impl WasmResult for Result { fn e(self) -> Result { self.map_err(WasmError::e) } } +#[throws(JsValue)] +fn get_packed_str(js: &JsValue) -> String { + js.as_string().ok_or(JsZCoordTypeError).e()? +} + #[throws(JsValue)] #[wasm_bindgen] pub fn check(packed: &JsValue) { - let s = packed.as_string().ok_or( - "packed Z coordinate wrong JS type (not a string)", - ).e()?; - ZCoord::check_str(&s).e()?; + ZCoord::check_str(&get_packed_str(packed)?).e()?; } -//const X : &'static str = "invalid value passed to wasm"; -/* +#[wasm_bindgen] +pub struct ZCoordIterator (zcoord::BoxedIterator); + #[throws(JsValue)] #[wasm_bindgen] -pub fn mutable(s: String) -> ZCoordIterator { - ZCoordIterator(ZCoord::from_str(&s).ok_or(X)?.clone_mut()) -}*/ +pub fn range(a: &JsValue, b: &JsValue, count: zcoord::RangeCount) + -> ZCoordIterator { + #[throws(JsValue)] + fn get1(js: &JsValue) -> Option { + if js.is_null() { return None } + let s = get_packed_str(js)?; + let m = Mutable::from_str(&s).e()?; + Some(m) + } + + let a = get1(a)?; + let b = get1(b)?; + let inner = Mutable::some_range(a.as_ref(),b.as_ref(),count).e()?; + ZCoordIterator(inner) +} #[wasm_bindgen] impl ZCoordIterator { - pub fn next(&mut self) -> u32 { 42 } + pub fn next(&mut self) -> JsValue { + let packed = match self.0.next() { + None => return JsValue::NULL, + Some(p) => p, + }; + packed.to_string().into() + } } #[wasm_bindgen] diff --git a/zcoord/zcoord.rs b/zcoord/zcoord.rs index 04996d99..39ad3599 100644 --- a/zcoord/zcoord.rs +++ b/zcoord/zcoord.rs @@ -76,6 +76,8 @@ use thiserror::Error; //---------- core definitions ---------- +pub type RangeCount = u32; + const BITS_PER_DIGIT : usize = 5; const DIGITS_PER_LIMB : usize = 10; @@ -288,7 +290,7 @@ impl Mutable { } #[throws(RangeBackwards)] - fn range_core(a: &Mutable, b: &Mutable, count: u32) + fn range_core(a: &Mutable, b: &Mutable, count: RangeCount) -> IteratorCore { type ASRD = AddSubRangeDelta; let count = count as RawLimbVal; @@ -344,7 +346,8 @@ impl Mutable { } #[throws(RangeBackwards)] - pub fn range_upto(&self, other: &Mutable, count: u32) -> RangeIterator { + pub fn range_upto(&self, other: &Mutable, count: RangeCount) + -> RangeIterator { Mutable::range_core(self, other, count)?.take(count as usize) } } @@ -367,8 +370,8 @@ impl Mutable { IteratorCore { current: self, aso } } #[throws(LogicError)] - pub fn some_range(a: Option<&Mutable>, b: Option<&Mutable>, count: u32) - -> BoxedIterator { + pub fn some_range(a: Option<&Mutable>, b: Option<&Mutable>, + count: RangeCount) -> BoxedIterator { fn mk>(x: T) -> BoxedIterator { Box::new(x) } match (a, b) {