Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions Cargo.toml

This file was deleted.

26 changes: 10 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,26 @@ const xml = `
</population>
`

parser.parseString(xml, (err, res) => {
...
})
const json = await parser.parseString(xml, false)

parser.parseFile('/a/xml/file/somewhere.xml', { object: true }, (err, res) => {
...
})
const object = await parser.parseFile('/a/xml/file/somewhere.xml')

```

## API

### `parseString(xmlString[, options], callback)`
### `async parseString(xmlString[, parse])`
- `xmlString` - A string that represents an XML
- `options` - an optional object where:
- `object` - Parse JSON string to Object. default `false`
- `callback` - a function with the signature `function (err, result)`
- `parse` - Parse JSON string to Object. default `true`
Returns `Object` or `String` dependently on the `parse` argument value.

### `parseFile(filePath[, options], callback)`
- `filePath` - Relative or absolute path to an `.xml` file
- `options` - an optional object where:
- `object` - Parse JSON string to Object. default `false`
- `callback` - a function with the signature `function (err, result)`
### `async parseFile(filePath[, parse])`
- `filePath` - Relative or absolute path to an `.xml` file
- `parse` - Parse JSON string to Object. default `true`
Returns `Object` or `String` dependently on the `parse` argument value.


## Benchmark
## Benchmark (TO BE CLARIFIED)
Results from a i7 2.2 Ghz

```
Expand Down
9 changes: 7 additions & 2 deletions benchmark/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,17 @@ function runSync (fn, opts) {
}

async.series([
(next) => runAsync(parserXmlToJson, { object: true }, (timeTaken) => {
(next) => {
const timeTaken = runSync(
async(opts) => {await parserXmlToJson(opts)},
{}
)

table.cell('Package', 'parser-xml2json (rust)')
table.cell('Time taken', timeTaken)
table.newRow()
next()
}),
},
(next) => runAsync(xml2js, {}, (timeTaken) => {
table.cell('Package', 'xml2js (js)')
table.cell('Time taken', timeTaken)
Expand Down
52 changes: 15 additions & 37 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,27 @@
const ffi = require('ffi')
const {parser} = require('../native')
const path = require('path')
const fs = require('fs')

// Import rust lib
const rustEmbedLocation = path.join(__dirname, '../target/release/libembed')
const rustLib = ffi.Library(rustEmbedLocation, {
parser: ['void', ['string', 'pointer']]
})

function parseString (content, options, done) {
if (typeof options === 'function') {
done = options
options = {}
}
async function parseString(content, parse = true) {
const start = new Date()

let callback = ffi.Callback('void', ['int', 'string'], (err, res) => {
if (err) {
return done(new Error(res))
}
const result = parser(content)
const finish = new Date()
console.log(`Parsed in ${(finish - start) / 1000}s`)

if (options.object) {
try {
res = JSON.parse(res)
} catch (e) {
return done(e)
}
}

done(null, res)
})

rustLib.parser(content, callback)
if(result[0] !== '{')
throw new Error(result)
else
return parse ? JSON.parse(result) : result
}

function parseFile (filePath, options, done) {
fs.readFile(path.resolve(filePath), 'utf8', (err, content) => {
if (err) {
return done(err)
}

parseString(content, options, done)
})
async function parseFile (filePath, options) {
const content = fs.readFileSync(path.resolve(filePath), 'utf8')
return await parseString(content, options)
}

module.exports = {
parseString,
parseFile
parseString,
parseFile,
}
23 changes: 23 additions & 0 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "parser-xml2json"
version = "0.2.0"
authors = ["Ricardo Barros <[email protected]>", "Alexandr Priezzhev <[email protected]>"]
license = "MIT"
build = "build.rs"

[lib]
name = "parser_xml2json"
crate-type = ["dylib"]

[build-dependencies]
neon-build = "0.1.18"

[dependencies]
neon = "0.1.18"
treexml = "0.6.1"
serde_json = "1.0.2"

[dependencies.node2object]
# version = "0.15.*"
git = "https://github.com/priezz/node2object"
rev = "553b5683307fe3278d54d7909dc68a4622880771"
1 change: 1 addition & 0 deletions native/artifacts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"active":"release","targets":{"release":{"rustc":"rustc 1.21.0-nightly (599be0d18 2017-07-26)","env":{"npm_config_target":null,"npm_config_arch":null,"npm_config_target_arch":null,"npm_config_disturl":null,"npm_config_runtime":null,"npm_config_build_from_source":null,"npm_config_devdir":null}}}}
7 changes: 7 additions & 0 deletions native/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extern crate neon_build;

fn main() {
neon_build::setup(); // must be called in build.rs

// add project-specific build logic here...
}
Binary file added native/index.node
Binary file not shown.
34 changes: 34 additions & 0 deletions native/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#[macro_use]
extern crate neon;
use neon::vm::{Call, JsResult};
use neon::js::JsString;
use neon::mem::Handle;

extern crate treexml;
extern crate node2object;
extern crate serde_json;

use std::error::Error;


fn parser(call: Call) -> JsResult<JsString> {
let scope = call.scope;
let string: Handle<JsString> = try!(try!(call.arguments.require(scope, 0)).check::<JsString>());
let tree = treexml::Document::parse(string.value().as_bytes());

let result = match tree {
Ok(v) => {
let dom_root = v.root.unwrap();
serde_json::Value::Object(node2object::node2object(&dom_root)).to_string()
},
Err(e) => String::from(e.description())
};

Ok(JsString::new(scope, &result).unwrap())
}


register_module!(m, {
try!(m.export("parser", parser));
Ok(())
});
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
{
"name": "parser-xml2json",
"version": "0.1.1",
"version": "0.2.0",
"description": "Blazing fast XML parser to JSON written in Rust",
"main": "lib/index.js",
"scripts": {
"lint": "standard || snazzy",
"test": "mocha ",
"postinstall": "cargo build --release"
},
"keywords": [
"xml",
"json",
"parser"
],
"repository": {
"type": "git",
"url": "https://github.com/ricardofbarros/parser-xml2json.git"
"url": "https://github.com/ricardofbarros/parser-xml2json"
},
"bugs": {
"url": "https://github.com/ricardofbarros/parser-xml2json/issues"
},
"homepage": "https://github.com/ricardofbarros/parser-xml2json",
"author": {
"name": "Ricardo Barros",
"email": "[email protected]"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/ricardofbarros/parser-xml2json/issues"
"keywords": [
"xml",
"json",
"parser"
],
"scripts": {
"lint": "standard || snazzy",
"test": "mocha",
"install": "neon build"
},
"homepage": "https://github.com/ricardofbarros/parser-xml2json",
"dependencies": {
"ffi": "^2.2.0"
"neon-cli": "^0.1.18"
},
"devDependencies": {
"chai": "^3.5.0",
Expand Down
30 changes: 0 additions & 30 deletions src/embed.rs

This file was deleted.