diff --git a/Cargo.toml b/Cargo.toml index 2e26b8e..83870b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sourmash" -version = "0.1.1" +version = "0.2.1" authors = ["Luiz Irber "] description = "MinHash sketches for genomic data" repository = "https://github.com/luizirber/sourmash-rust" @@ -23,6 +23,7 @@ cbindgen = "0.6.1" [dependencies] backtrace = "0.3.4" +cfg-if = "0.1" error-chain = "0.12" finch = { version = "0.1.6", optional = true } lazy_static = "1.0.0" @@ -32,4 +33,10 @@ needletail = { version = "~0.2.1", optional = true } ordslice = "0.3.0" serde = "1.0" serde_derive = "1.0" -serde_json = "1.0.2" +serde_json = "1.0" + +#TODO: wasm-pack can't check optionals or this kind of config yet... +# [target. 'cfg(target_arch = "wasm32")'.dependencies] +[dependencies.wasm-bindgen] +version = "^0.2" +features = ["serde-serialize"] diff --git a/Makefile b/Makefile index 30e3c8c..f9a7448 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,8 @@ test: target/sourmash.h: src/lib.rs src/ffi.rs src/errors.rs RUST_BACKTRACE=1 cbindgen --clean -c cbindgen.toml -o $@ +wasm: +# wasm-pack init --mode no-installs + wasm-pack init + .phony: test diff --git a/src/lib.rs b/src/lib.rs index 1b828c5..413c480 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,7 @@ extern crate backtrace; +#[macro_use] +extern crate cfg_if; + extern crate md5; extern crate murmurhash3; extern crate ordslice; @@ -29,9 +32,6 @@ pub mod ffi; #[cfg(feature = "from-finch")] pub mod from; -use serde::de::{Deserialize, Deserializer}; -use serde::ser::{Serialize, SerializeStruct, Serializer}; - use std::collections::HashMap; use std::collections::HashSet; use std::hash::{BuildHasherDefault, Hasher}; @@ -40,6 +40,8 @@ use std::str; use murmurhash3::murmurhash3_x64_128; use ordslice::Ext; +use serde::de::{Deserialize, Deserializer}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; use errors::{ErrorKind, Result}; @@ -72,15 +74,37 @@ impl Hasher for NoHashHasher { } } -#[derive(Debug, Clone, PartialEq)] -pub struct KmerMinHash { - pub num: u32, - pub ksize: u32, - pub is_protein: bool, - pub seed: u64, - pub max_hash: u64, - pub mins: Vec, - pub abunds: Option>, +cfg_if! { + if #[cfg(target_arch = "wasm32")] { + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + pub mod wasm; + + #[wasm_bindgen] + #[derive(Debug, Clone, PartialEq)] + pub struct KmerMinHash { + num: u32, + ksize: u32, + is_protein: bool, + seed: u64, + max_hash: u64, + mins: Vec, + abunds: Option>, + } + } else { + #[derive(Debug, Clone, PartialEq)] + pub struct KmerMinHash { + pub num: u32, + pub ksize: u32, + pub is_protein: bool, + pub seed: u64, + pub max_hash: u64, + pub mins: Vec, + pub abunds: Option>, + } + } } impl Default for KmerMinHash { @@ -531,6 +555,10 @@ impl KmerMinHash { return Ok(0.0); } } + + pub fn to_vec(&self) -> Vec { + self.mins.clone() + } } #[derive(Serialize, Deserialize, Debug)] diff --git a/src/wasm.rs b/src/wasm.rs new file mode 100644 index 0000000..72bd4e5 --- /dev/null +++ b/src/wasm.rs @@ -0,0 +1,45 @@ +use wasm_bindgen::prelude::*; + +use serde_json; + +use KmerMinHash; + +#[wasm_bindgen] +impl KmerMinHash { + #[wasm_bindgen(constructor)] + pub fn new_with_scaled( + num: u32, + ksize: u32, + is_protein: bool, + seed: u32, + scaled: u32, + track_abundance: bool, + ) -> KmerMinHash { + let max_hash = if num != 0 { + 0 + } else if scaled == 0 { + u64::max_value() + } else { + u64::max_value() / scaled as u64 + }; + + KmerMinHash::new( + num, + ksize, + is_protein, + seed as u64, + max_hash, + track_abundance, + ) + } + + #[wasm_bindgen] + pub fn add_sequence_js(&mut self, buf: &str) { + self.add_sequence(buf.as_bytes(), true); + } + + #[wasm_bindgen] + pub fn to_json(&mut self) -> String { + serde_json::to_string(self).unwrap() + } +}