diff --git a/.gitignore b/.gitignore index 0b3cb79fd9fca0b6513ffc7fa9100a6c7f6b0a50..b8629cee13886923757d31c1aad1554a0f3af992 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ native/artifacts.json **/*~ **/node_modules **/.DS_Store + +*.bk + +*.wot diff --git a/lib/index.js b/lib/index.js index ab3e2715bb150865b1f8e276e66cc6cd2e9f5da6..6de2283e675f720373fd0c066458c04924f7d237 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,3 +1,20 @@ -var addon = require('../native'); +let WebOfTrust = require('../native').WebOfTrust; -console.log(addon.hello()); +{ + let wot = new WebOfTrust(3); + console.log(wot.getMaxCert()) + wot.setMaxCert(4); + console.log(wot.getMaxCert()) + console.log(wot.addNode()); + console.log(wot.getWoTSize()) +} + +console.log("-----") + +{ + let wot = new WebOfTrust("hey.wot"); + console.log(wot.getMaxCert()) + console.log(wot.addNode()); + console.log(wot.getWoTSize()); + console.log(wot.toFile("hey.wot")); +} diff --git a/native/src/lib.rs b/native/src/lib.rs index 5b9929c08d926d106f800af00861c090731a3cdb..a09a07bb7689f653cf0f16c0efbc68255cee3d1e 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -1,14 +1,280 @@ +//! `duniter-rs-wotb-js` is a crate providing Javascript bindings of `duniter-rs-wotb`. + #[macro_use] extern crate neon; +extern crate duniter_rs_wotb; + +use neon::js::{Value, JsInteger, JsString, JsBoolean, JsFunction, JsArray, JsNumber, JsObject, Object}; +use neon::js::class::{Class, JsClass}; +use neon::mem::Handle; +use neon::vm::{Throw, Lock}; + +use duniter_rs_wotb::{WebOfTrust, NodeId, NewLinkResult, RemovedLinkResult}; + + +declare_types! { + /// JS class wrapping WebOfTrust struct. + pub class JsWebOfTrust for WebOfTrust { + init(call) { + let scope = call.scope; + let arg0 = try!(call.arguments.require(scope, 0)); + + if let Some(max_cert) = arg0.downcast::<JsInteger>() { + let max_cert = max_cert.value(); + + match max_cert > 0 { + true => Ok(WebOfTrust::new(max_cert as usize)), + false => Err(Throw), + } + } else if let Some(path) = arg0.downcast::<JsString>() { + let path = path.value(); + + match WebOfTrust::from_file(path.as_str()) { + Some(wot) => Ok(wot), + None => Err(Throw), + } + } else { + Err(Throw) + } + } + + method toFile(call) { + let scope = call.scope; + let path = try!(try!(call.arguments.require(scope, 0)).to_string(scope)).value(); + + let result = call.arguments.this(scope).grab(|wot| { + wot.to_file(path.as_str()) + }); + + Ok(JsBoolean::new(scope, result).upcast()) + } + + method addNode(call) { + let scope = call.scope; + + let id = call.arguments.this(scope).grab(|wot| { + wot.add_node() + }); + + Ok(JsInteger::new(scope, *id as i32).upcast()) + } + + method removeNode(call) { + let scope = call.scope; + + let id = call.arguments.this(scope).grab(|wot| { + match wot.remove_node() { + Some(id) => *id as i32, + None => -1, + } + }); + + Ok(JsInteger::new(scope, id).upcast()) + } + + method getSentries(call) { + let scope = call.scope; + + let arg0 = try!(call.arguments.require(scope, 0)); + let d_min = try!(arg0.check::<JsInteger>()).value() as usize; + + let array = call.arguments.this(scope).grab(|wot| { + wot.get_sentries(d_min) + }); + + let jsarray: Handle<JsArray> = JsArray::new(scope, array.len() as u32); + + for (index, &item) in array.iter().enumerate() { + try!(jsarray.set(index as u32, JsInteger::new(scope, *item as i32))); + } + + Ok(jsarray.upcast()) + } + + method getNonSentries(call) { + let scope = call.scope; + + let arg0 = try!(call.arguments.require(scope, 0)); + let d_min = try!(arg0.check::<JsInteger>()).value() as usize; + + let array = call.arguments.this(scope).grab(|wot| { + wot.get_non_sentries(d_min) + }); + + let jsarray: Handle<JsArray> = JsArray::new(scope, array.len() as u32); + + for (index, &item) in array.iter().enumerate() { + try!(jsarray.set(index as u32, JsInteger::new(scope, *item as i32))); + } + + Ok(jsarray.upcast()) + } + + method getDisabled(call) { + let scope = call.scope; + + let array = call.arguments.this(scope).grab(|wot| { + wot.get_disabled() + }); + + let jsarray: Handle<JsArray> = JsArray::new(scope, array.len() as u32); + + for (index, &item) in array.iter().enumerate() { + try!(jsarray.set(index as u32, JsInteger::new(scope, *item as i32))); + } + + Ok(jsarray.upcast()) + } + + method getPaths(call) { + let scope = call.scope; + + let from = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let to = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as usize; + let k_max = try!(try!(call.arguments.require(scope, 2)).check::<JsInteger>()).value() as u32; + + let paths = call.arguments.this(scope).grab(|wot| { + wot.get_paths(NodeId(from), NodeId(to), k_max) + }); + + let jsarray: Handle<JsArray> = JsArray::new(scope, paths.len() as u32); + + for(index, ref inner_array) in paths.iter().enumerate() { + let inner_jsarray: Handle<JsArray> = JsArray::new(scope, inner_array.len() as u32); + + for(inner_index, &item) in inner_array.iter().enumerate() { + try!(inner_jsarray.set(inner_index as u32, JsInteger::new(scope, *item as i32))); + } + + try!(jsarray.set(index as u32, inner_jsarray)); + } + + Ok(jsarray.upcast()) + } + + method getWoTSize(call) { + let scope = call.scope; + + let size = call.arguments.this(scope).grab(|wot| { + wot.size() + }); + + Ok(JsInteger::new(scope, size as i32).upcast()) + } + + method isEnabled(call) { + let scope = call.scope; + + let node = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + + match call.arguments.this(scope).grab(|wot| { + wot.is_enabled(NodeId(node)) + }) { + Some(state) => Ok(JsBoolean::new(scope, state).upcast()), + None => Err(Throw), + } + } + + method setEnabled(call) { + let scope = call.scope; + + let node = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let state = try!(try!(call.arguments.require(scope, 1)).check::<JsBoolean>()).value(); + + match call.arguments.this(scope).grab(|wot| { + wot.set_enabled(NodeId(node), state) + }) { + Some(state) => Ok(JsBoolean::new(scope, state).upcast()), + None => Err(Throw), + } + } + + method addLink(call) { + let scope = call.scope; + + let from = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let to = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as usize; + + match call.arguments.this(scope).grab(|wot| { + wot.add_link(NodeId(from), NodeId(to)) + }) { + NewLinkResult::Ok(count) | + NewLinkResult::AlreadyCertified(count) | + NewLinkResult::AllCertificationsUsed(count) => Ok(JsInteger::new(scope, count as i32).upcast()), + _ => Err(Throw), + } + } + + method removeLink(call) { + let scope = call.scope; + + let from = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let to = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as usize; + + match call.arguments.this(scope).grab(|wot| { + wot.remove_link(NodeId(from), NodeId(to)) + }) { + RemovedLinkResult::Removed(count) => Ok(JsInteger::new(scope, count as i32).upcast()), + _ => Err(Throw), + } + } + + method existsLink(call) { + let scope = call.scope; + + let from = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let to = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as usize; + + let result = call.arguments.this(scope).grab(|wot| { + wot.exists_link(NodeId(from), NodeId(to)) + }); + + Ok(JsBoolean::new(scope, result).upcast()) + } + + method isOutdistanced(call) { + let scope = call.scope; + + let node = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + let d_min = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value() as u32; + let d_max = try!(try!(call.arguments.require(scope, 2)).check::<JsInteger>()).value() as u32; + let x_percent = try!(try!(call.arguments.require(scope, 3)).check::<JsNumber>()).value() as f64; + + match call.arguments.this(scope).grab(|wot| { + wot.is_outdistanced(NodeId(node), d_min, d_max, x_percent) + }) { + Some(result) => Ok(JsBoolean::new(scope, result).upcast()), + None => Err(Throw), + } + } + + method setMaxCert(call) { + let scope = call.scope; + + let max_cert = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize; + + call.arguments.this(scope).grab(|wot| { + wot.max_cert = max_cert; + }); + + Ok(JsObject::new(scope).upcast()) + } + + method getMaxCert(call) { + let scope = call.scope; -use neon::vm::{Call, JsResult}; -use neon::js::JsString; + let max_cert = call.arguments.this(scope).grab(|wot| { + wot.max_cert + }); -fn hello(call: Call) -> JsResult<JsString> { - let scope = call.scope; - Ok(JsString::new(scope, "hello node").unwrap()) + Ok(JsInteger::new(scope, max_cert as i32).upcast()) + } + } } register_module!(m, { - m.export("hello", hello) + let class: Handle<JsClass<JsWebOfTrust>> = try!(JsWebOfTrust::class(m.scope)); + let constructor: Handle<JsFunction<JsWebOfTrust>> = try!(class.constructor(m.scope)); + try!(m.exports.set("WebOfTrust", constructor)); + Ok(()) });