Skip to content

Instantly share code, notes, and snippets.

@enpedasi
Created May 20, 2018 13:01
Show Gist options
  • Save enpedasi/a76c238d7aa78744975e3f0065c65897 to your computer and use it in GitHub Desktop.
Save enpedasi/a76c238d7aa78744975e3f0065c65897 to your computer and use it in GitHub Desktop.
rustler nif example
#[macro_use] extern crate rustler;
#[macro_use] extern crate rustler_codegen;
#[macro_use] extern crate lazy_static;
extern crate kana;
use rustler::{NifEnv, NifTerm, NifResult, NifEncoder};
use rustler::types::atom::NifAtom;
use rustler::types::map::NifMapIterator;
use kana::*;
mod atoms {
rustler_atoms! {
atom ok;
//atom error;
//atom __true__ = "true";
//atom __false__ = "false";
}
}
rustler_export_nifs! {
"Elixir.NifExample",
[("add", 2, add),
("concat", 2, concat),
("hira2kana", 1, rust_hira2kana),
("half2kana", 1, rust_half2kana),
("printTuple", 1, print_tuple),
("printMap",1, print_map)
],
None
}
fn add<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
let num1: i64 = try!(args[0].decode());
let num2: i64 = try!(args[1].decode());
Ok((atoms::ok(), num1 + num2).encode(env))
}
fn concat<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
let s1: String = try!(args[0].decode());
let s2: String = try!(args[1].decode());
// Ok((atoms::ok(), [s1 , hira2kata(&s2)].join("")).encode(env))
Ok((atoms::ok(), [s1 , s2].join("")).encode(env))
}
fn rust_hira2kana<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
let s1: String = try!(args[0].decode());
Ok((hira2kata(&s1)).encode(env))
}
fn rust_half2kana<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
let s1: String = try!(args[0].decode());
Ok((half2kana(&s1)).encode(env))
}
fn print_tuple<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
// The types must be known beforehand to decode a tuple. The Turbofish is used here to set the types
let tuple = (args[0]).decode::<(NifAtom, f64, i64, String)>()?; //Note that "?" is used here instead of "try!"
println!("Atom: {:?}, Float: {}, Integer: {}, String: {}", tuple.0, tuple.1, tuple.2, tuple.3);
Ok((atoms::ok(),tuple.3).encode(env))
}
fn print_map<'a>(env: NifEnv<'a>, args: &[NifTerm<'a>]) -> NifResult<NifTerm<'a>> {
// Maps can use the built-in NifMapIterator which makes iterating over the entries simple
let mut map = NifMapIterator::new(args[0]).expect("Should be a map in the argument");
for x in map {
println!("{:?}", x); //Doing more here will likely require matching and knowledge of types in the map
}
Ok((atoms::ok().encode(env)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment