I’m trying to FFI https://github.com/Leonidas-from-XIV/node-xml2js#simple-as-pie-usage
The API is as follows:
parser.parseString(data, function (err, result) {
console.dir(result);
console.log('Done');
});
When expanding this using https://blog.drewolson.org/purescript-async-ffi as a reference, I get
exports._parseString = function (parser) {
return function (data) {
return function (onError, onSuccess) {
parser.parseString(data, function (err, data) {
if (err) {
onError(err);
return;
}
onSuccess(data);
});
return function (cancelError, onCancelerError, onCancelerSuccess) {
onCancelerSuccess();
};
};
};
};
And
parseString :: Parser -> String -> Aff Foreign
parseString p s = fromEffectFnAff $ _parseString p s
on the PureScript side.
Is there a way to achieve this with a whole lot less JS code, e.g.
exports._parseString = function(parser, input, cb) { parser.parseString(input, cb) }
paluh
February 16, 2020, 5:05pm
#4
EDIT:
I’ve just checked your linked docs and there is xml2js
promised based API xml2js.parseStringPromise
. In the linked article there is a solution for simple promise based FFI so please ignore my all my hacky responses and use promise based API + aff-promise
directly.
OLD:
Maybe a bit hacky way by using node promisify + aff-promise. I hope I typed this correctly this time:
const util = require('util');
exports.parseStringImpl = function(parser) {
return function() {
return util.promisify(function(s, c) { parser.parseString(s, c); });
}
}
and
import Control.Promise as Promise
foreign import parseStringImpl :: Parser -> Effect (String -> Promise ...)
parseString parser s = liftEffect (parseStringImpl parser) >>= \p -> Promise.toAff (p s)
Not tested so it is possibly a rubbish
Thanks for the aff-promise
hint. Shortest JS code I could come up with:
exports._parseStringPromise =
function(parser, data) { return parser.parseStringPromise(data) }
foreign import _parseStringPromise ::
EffectFn2 Parser String (Promise Foreign)
parseString :: Parser -> String -> Aff Foreign
parseString p s = toAffE $ runEffectFn2 _parseStringPromise p s
1 Like
rnons
February 19, 2020, 2:12am
#6
You can use arrow function to get rid of EffectFn2
and runEffectFn2
. Not tested
exports._parseStringPromise =
parser => data => () => parser.parseStringPromise(data)
foreign import _parseStringPromise ::
Parser -> String -> Effect (Promise Foreign)
parseString :: Parser -> String -> Aff Foreign
parseString p s = toAffE $ parseStringPromise p s