chiark / gitweb /
bindings
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 12 Oct 2020 00:14:35 +0000 (01:14 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 12 Oct 2020 00:14:35 +0000 (01:14 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock.example
wasm/Cargo.toml
wasm/wasm.rs
zcoord/zcoord.rs

index 79fdb2feeb4719b796daa4eef577cdeab91fdfdc..e7a7636aca0376ef7082ef4961e9d2e86b0ba316 100644 (file)
@@ -1015,6 +1015,7 @@ dependencies = [
  "fehler",
  "js-sys",
  "otter-zcoord",
+ "thiserror",
  "wasm-bindgen",
  "wee_alloc",
 ]
index 58065953fd35d967bfa08bb8549ebebb233f17b7..cffff750c136f14b705207cffabdbffa4dce910f 100644 (file)
@@ -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 }
index 1bff002833d80efbfe4c4af46b47d42a1ea12ab6..7bea8ecf57ca92482416ad0677897d8c945b8c6f 100644 (file)
@@ -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<E:Display, V> WasmResult<V> for Result<V, E> {
   fn e(self) -> Result<V, JsValue> { 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<Mutable> {
+    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]
index 04996d99ea80410085d1c37014c6fe5ceb6af062..39ad3599ca86047a2f21765b06900f3e4c667b3c 100644 (file)
@@ -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<AddSubRangeDelta> {
     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<T:'static + Iterator<Item=ZCoord>>(x: T) -> BoxedIterator
         { Box::new(x) }
     match (a, b) {