Skip to content

Instantly share code, notes, and snippets.

@dherman
Created January 8, 2023 00:38
Show Gist options
  • Save dherman/345ab646235bfc6644b063e5b9b45e7a to your computer and use it in GitHub Desktop.
Save dherman/345ab646235bfc6644b063e5b9b45e7a to your computer and use it in GitHub Desktop.
small example of exposing a Rust crate's functionality through tasks and promises
use neon::prelude::*;
use neon::types::buffer::TypedArray;
use linkify::{LinkFinder, LinkKind, Span};
// Purely indexed version of Span<'t> that removes reference to the original string.
struct IndexSpan {
start: u32,
end: u32,
kind: u32,
}
fn index(span: Span) -> IndexSpan {
IndexSpan {
start: span.start() as u32,
end: span.end() as u32,
kind: match span.kind() {
Some(LinkKind::Url) => 1,
Some(LinkKind::Email) => 2,
_ => 0,
}
}
}
fn linkify(mut cx: FunctionContext) -> JsResult<JsPromise> {
let text = cx.argument::<JsString>(0)?.value(&mut cx);
let promise = cx
.task(move || {
let spans: Vec<_> = LinkFinder::new().spans(&text).map(index).collect();
spans
})
.promise(|mut cx, spans| {
let mut array = JsUint32Array::new(&mut cx, spans.len() * 3)?;
let slice = array.as_mut_slice(&mut cx);
for (i, span) in spans.iter().enumerate() {
let base = i * 3;
slice[base] = span.start;
slice[base + 1] = span.end;
slice[base + 2] = span.kind;
}
Ok(array)
});
Ok(promise)
}
#[neon::main]
fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("linkify", linkify)?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment