use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn molecule_report_json(smiles: &str) -> Result<String, JsValue> {
let report = chematic_chem::molecule_report(smiles)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
serde_json::to_string(&report)
.map_err(|e| JsValue::from_str(&format!("JSON serialization failed: {}", e)))
}
#[wasm_bindgen]
pub fn compare_molecules_json(smiles1: &str, smiles2: &str) -> Result<String, JsValue> {
let smiles = [smiles1, smiles2];
let comparison = chematic_chem::compare_molecules(&smiles)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
serde_json::to_string(&comparison)
.map_err(|e| JsValue::from_str(&format!("JSON serialization failed: {}", e)))
}
#[wasm_bindgen]
pub fn compare_molecules_batch_json(
smiles_batch: &str,
delimiter: &str,
) -> Result<String, JsValue> {
let smiles_vec: Vec<&str> = smiles_batch.split(delimiter).collect();
let comparison = chematic_chem::compare_molecules(&smiles_vec)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
serde_json::to_string(&comparison)
.map_err(|e| JsValue::from_str(&format!("JSON serialization failed: {}", e)))
}
#[wasm_bindgen]
pub fn screen_smiles_json(smiles_batch: &str, delimiter: &str) -> String {
let smiles_vec: Vec<&str> = smiles_batch.split(delimiter).collect();
let report = chematic_chem::screen_smiles(&smiles_vec);
serde_json::to_string(&report)
.unwrap_or_else(|_| "{\"error\": \"JSON serialization failed\"}".to_string())
}
#[wasm_bindgen]
pub fn generate_3d_from_smiles(smiles: &str) -> Result<String, JsValue> {
let mol = chematic_smiles::parse(smiles)
.map_err(|e| JsValue::from_str(&format!("SMILES parse error: {}", e)))?;
let coords = chematic_3d::generate_coords(&mol);
let pdb_str = chematic_3d::write_pdb(&mol, &coords);
Ok(pdb_str)
}
#[wasm_bindgen]
pub fn generate_3d_optimized_pdb(smiles: &str) -> Result<String, JsValue> {
let mol = chematic_smiles::parse(smiles)
.map_err(|e| JsValue::from_str(&format!("SMILES parse error: {}", e)))?;
let coords = chematic_3d::generate_and_minimize_dreiding(&mol);
let pdb_str = chematic_3d::write_pdb(&mol, &coords);
Ok(pdb_str)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn workflow_json_serialization_aspirin() {
let report = chematic_chem::molecule_report("CC(=O)Oc1ccccc1C(=O)O").unwrap();
let json = serde_json::to_string(&report).unwrap();
assert!(json.contains("molecular_weight"), "JSON should contain molecular_weight");
assert!(json.contains("tpsa"), "JSON should contain tpsa");
}
#[test]
fn workflow_json_serialization_compare() {
let comparison = chematic_chem::compare_molecules(&["c1ccccc1", "Cc1ccccc1"]).unwrap();
let json = serde_json::to_string(&comparison).unwrap();
assert!(json.contains("pairwise"), "JSON should contain pairwise");
assert!(json.contains("ecfp4_tanimoto"), "JSON should have similarity metrics");
}
#[test]
fn workflow_json_serialization_screen() {
let report = chematic_chem::screen_smiles(&["c1ccccc1", "CC", "CCC"]);
let json = serde_json::to_string(&report).unwrap();
assert!(json.contains("records"), "JSON should contain records");
assert!(json.contains("maxmin_picks"), "JSON should contain diversity picks");
}
#[test]
fn distance_geometry_benzene_has_coords() {
let mol = chematic_smiles::parse("c1ccccc1").unwrap();
let coords = chematic_3d::generate_coords(&mol);
assert_eq!(coords.atom_count(), 6, "benzene has 6 carbons");
}
#[test]
fn distance_geometry_ethane_reasonable_distance() {
let mol = chematic_smiles::parse("CC").unwrap();
let coords = chematic_3d::generate_coords(&mol);
let p0 = coords.get(chematic_core::AtomIdx(0));
let p1 = coords.get(chematic_core::AtomIdx(1));
let dist = p0.distance(&p1);
assert!((dist - 1.54).abs() < 0.15, "C-C distance should be ~1.54 Å");
}
}