Skip to content

Commit

Permalink
Remove duplication of Record fields in JS. Implement display trait to…
Browse files Browse the repository at this point in the history
… get nice to_string()
  • Loading branch information
vemonet committed Dec 15, 2023
1 parent 364c069 commit ff60688
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 52 deletions.
13 changes: 4 additions & 9 deletions js/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,15 @@

async function main() {
await init();
const rec1 = new Record("doid", "http://purl.obolibrary.org/obo/DOID_", [], []);
console.log(rec1);

// const rec2 = {
// prefix: "doid",
// uri_prefix: "http://purl.obolibrary.org/obo/DOID_",
// prefix_synonyms: [],
// uri_prefix_synonyms: [],
// };
const rec1 = new Record("obo", "http://purl.obolibrary.org/obo/", [], []);
console.log(rec1.toString());
console.log(rec1.toJs());

// const converter = new Converter();
// converter.addRecord(rec1);

const converter = await getOboConverter();
console.log(converter.toString())

const compressedUri = converter.compress("http://purl.obolibrary.org/obo/DOID_1234");
const expandedUri = converter.expand("DOID:1234");
Expand Down
40 changes: 23 additions & 17 deletions js/src/curies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ use std::collections::HashSet;
use curies::{sources::get_obo_converter, Converter, Record};
use js_sys::Promise;
use serde::{Deserialize, Serialize};
use serde_wasm_bindgen::to_value;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::future_to_promise;

#[wasm_bindgen(js_name = Record )]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordJs {
// record: Record,
prefix: String,
uri_prefix: String,
prefix_synonyms: HashSet<String>,
uri_prefix_synonyms: HashSet<String>,
record: Record,
}

#[allow(clippy::inherent_to_string, clippy::wrong_self_convention)]
#[wasm_bindgen(js_class = Record)]
impl RecordJs {
#[wasm_bindgen(constructor)]
Expand All @@ -28,20 +26,23 @@ impl RecordJs {
let prefix_synonyms_set: HashSet<String> = prefix_synonyms.into_iter().collect();
let uri_prefix_synonyms_set: HashSet<String> = uri_prefix_synonyms.into_iter().collect();
Ok(Self {
prefix,
uri_prefix,
prefix_synonyms: prefix_synonyms_set,
uri_prefix_synonyms: uri_prefix_synonyms_set,
record: Record {
prefix,
uri_prefix,
prefix_synonyms: prefix_synonyms_set,
uri_prefix_synonyms: uri_prefix_synonyms_set,
},
})
}

fn into_record(self) -> Record {
Record {
prefix: self.prefix,
uri_prefix: self.uri_prefix,
prefix_synonyms: self.prefix_synonyms,
uri_prefix_synonyms: self.uri_prefix_synonyms,
}
#[wasm_bindgen(js_name = toJs)]
pub fn to_js(&self) -> Result<JsValue, JsValue> {
to_value(&self.record).map_err(|e| JsValue::from_str(&e.to_string()))
}

#[wasm_bindgen(js_name = toString)]
pub fn to_string(&self) -> String {
self.record.to_string()
}
}

Expand All @@ -65,7 +66,7 @@ impl ConverterJs {
#[wasm_bindgen(js_name = addRecord)]
pub fn add_record(&mut self, record: RecordJs) -> Result<(), JsValue> {
self.converter
.add_record(record.into_record())
.add_record(record.record)
.map(|_| ())
.map_err(|e| JsValue::from_str(&e.to_string()))
}
Expand All @@ -82,6 +83,11 @@ impl ConverterJs {
.map_err(|e| JsValue::from_str(&e.to_string()))
}

#[wasm_bindgen(js_name = toString)]
pub fn to_string(&self) -> String {
self.converter.to_string()
}

// #[wasm_bindgen(js_name = prefixMap)]
// pub fn prefix_map(&self) -> Result<JsValue, JsValue> {
// serde_wasm_bindgen::to_value(&self.converter.prefix_map).map_err(|e| e.into())
Expand Down
21 changes: 21 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use error::CuriesError;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::path::Path;
Expand Down Expand Up @@ -33,6 +34,16 @@ impl Record {
}
}

impl fmt::Display for Record {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Prefix: {}", self.prefix)?;
writeln!(f, "URI prefix: {}", self.uri_prefix)?;
writeln!(f, "Prefix synonyms: {:?}", self.prefix_synonyms)?;
writeln!(f, "URI prefix synonyms: {:?}", self.uri_prefix_synonyms)?;
Ok(())
}
}

/// A `Converter` is composed of 2 HashMaps (one for prefixes, one for URIs),
/// and a trie search to find the longest URI
/// # Examples
Expand Down Expand Up @@ -61,6 +72,7 @@ impl Record {
/// use_converter().unwrap();
/// ```
pub struct Converter {
records: Vec<Arc<Record>>,
prefix_map: HashMap<String, Arc<Record>>,
uri_map: HashMap<String, Arc<Record>>,
trie_builder: TrieBuilder<u8>,
Expand Down Expand Up @@ -89,6 +101,7 @@ impl Converter {
/// ```
pub fn new() -> Self {
Converter {
records: Vec::new(),
prefix_map: HashMap::new(),
uri_map: HashMap::new(),
trie_builder: TrieBuilder::new(),
Expand Down Expand Up @@ -168,6 +181,7 @@ impl Converter {
}
// TODO: check if synonyms are unique?

self.records.push(rec.clone());
self.prefix_map.insert(rec.prefix.clone(), rec.clone());
self.uri_map.insert(rec.uri_prefix.clone(), rec.clone());
self.trie_builder.push(&rec.uri_prefix);
Expand Down Expand Up @@ -246,6 +260,13 @@ impl Default for Converter {
}
}

impl fmt::Display for Converter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Converter contains {} records", self.records.len())?;
Ok(())
}
}

/// Trait to provide the data as URL, HashMap, string, or Path to file
// FutureExt::shared
#[async_trait(?Send)]
Expand Down
39 changes: 13 additions & 26 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};

/// Python bindings
#[pymodule]
fn curies(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
fn curies_rs(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add("__package__", "curies-rs")?;
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
m.add("__author__", env!("CARGO_PKG_AUTHORS").replace(':', "\n"))?;
Expand All @@ -20,22 +20,7 @@ fn curies(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
// #[pyclass(extends=Record, name = "Record", module = "curies_rs")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecordPy {
prefix: String,
uri_prefix: String,
prefix_synonyms: HashSet<String>,
uri_prefix_synonyms: HashSet<String>,
}

impl RecordPy {
#[allow(clippy::wrong_self_convention)]
fn into_record(&self) -> Record {
Record {
prefix: self.prefix.clone(),
uri_prefix: self.uri_prefix.clone(),
prefix_synonyms: self.prefix_synonyms.clone(),
uri_prefix_synonyms: self.uri_prefix_synonyms.clone(),
}
}
record: Record,
}

#[pymethods]
Expand All @@ -49,17 +34,19 @@ impl RecordPy {
uri_prefix_synonyms: Vec<String>,
) -> PyResult<Self> {
Ok(Self {
prefix,
uri_prefix,
prefix_synonyms: prefix_synonyms.into_iter().collect(),
uri_prefix_synonyms: uri_prefix_synonyms.into_iter().collect(),
record: Record {
prefix,
uri_prefix,
prefix_synonyms: prefix_synonyms.into_iter().collect(),
uri_prefix_synonyms: uri_prefix_synonyms.into_iter().collect(),
},
})
}

// Return the Record as a python dictionary
#[pyo3(text_signature = "($self)")]
fn dict(&self, py: Python<'_>) -> PyResult<PyObject> {
pythonize(py, &self).map_err(|e| {
pythonize(py, &self.record).map_err(|e| {
PyErr::new::<PyException, _>(format!("Error converting struct Record to dict: {e}"))
})
}
Expand All @@ -85,15 +72,15 @@ impl ConverterPy {
}

#[pyo3(text_signature = "($self, record)")]
fn add_record(&mut self, record: &RecordPy) -> PyResult<()> {
fn add_record(&mut self, record: RecordPy) -> PyResult<()> {
self.converter
.add_record(record.into_record())
.map_err(|e| PyErr::new::<PyException, _>(format!("Error Checking: {e}")))
.add_record(record.record)
.map_err(|e| PyErr::new::<PyException, _>(e.to_string()))
}

fn compress(&self, uri: String) -> PyResult<String> {
self.converter
.compress(&uri)
.map_err(|e| PyErr::new::<PyException, _>(format!("Error Checking: {e}")))
.map_err(|e| PyErr::new::<PyException, _>(e.to_string()))
}
}

0 comments on commit ff60688

Please sign in to comment.