aboutsummaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
authorJordan Bracco <href@random.sh>2021-11-12 00:15:31 +0100
committerJordan Bracco <href@random.sh>2021-11-12 00:15:31 +0100
commit3c6471ed8174b870f8d463e8f39a781f8c731471 (patch)
treef304ec29b980883387cba56033fabaffaf6cd2fd /native
initial commit
Diffstat (limited to 'native')
-rw-r--r--native/treebitmap_nif/.cargo/config12
-rw-r--r--native/treebitmap_nif/.gitignore1
-rw-r--r--native/treebitmap_nif/Cargo.lock120
-rw-r--r--native/treebitmap_nif/Cargo.toml14
-rw-r--r--native/treebitmap_nif/README.md20
-rw-r--r--native/treebitmap_nif/src/lib.rs107
6 files changed, 274 insertions, 0 deletions
diff --git a/native/treebitmap_nif/.cargo/config b/native/treebitmap_nif/.cargo/config
new file mode 100644
index 0000000..1cb1d94
--- /dev/null
+++ b/native/treebitmap_nif/.cargo/config
@@ -0,0 +1,12 @@
+[target.x86_64-apple-darwin]
+rustflags = [
+ "-C", "link-arg=-undefined",
+ "-C", "link-arg=dynamic_lookup",
+]
+
+[target.aarch64-apple-darwin]
+rustflags = [
+ "-C", "link-arg=-undefined",
+ "-C", "link-arg=dynamic_lookup",
+]
+
diff --git a/native/treebitmap_nif/.gitignore b/native/treebitmap_nif/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/native/treebitmap_nif/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/native/treebitmap_nif/Cargo.lock b/native/treebitmap_nif/Cargo.lock
new file mode 100644
index 0000000..c181954
--- /dev/null
+++ b/native/treebitmap_nif/Cargo.lock
@@ -0,0 +1,120 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rustler"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b787d3b2a80007f41cd4c0c310cdeb3936192768159585f65ecc7e96faf97fc3"
+dependencies = [
+ "lazy_static",
+ "rustler_codegen",
+ "rustler_sys",
+]
+
+[[package]]
+name = "rustler_codegen"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5a1f867002b6f0130f47abf215cac4405646db6f5d7b009b21c890980490aa4"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "rustler_sys"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cb382fde4f421c51555919e9920b058c0286f6bf59e53d02eb4d281eae6758b"
+dependencies = [
+ "unreachable",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "treebitmap"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bf423939ac9ccf4083788879b883a7149176586f9cf8b0fb1fd88b66ad692b5"
+
+[[package]]
+name = "treebitmap_nif"
+version = "0.1.0"
+dependencies = [
+ "rustler",
+ "treebitmap",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "unreachable"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
+dependencies = [
+ "void",
+]
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
diff --git a/native/treebitmap_nif/Cargo.toml b/native/treebitmap_nif/Cargo.toml
new file mode 100644
index 0000000..0c14233
--- /dev/null
+++ b/native/treebitmap_nif/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "treebitmap_nif"
+version = "0.1.0"
+authors = []
+edition = "2018"
+
+[lib]
+name = "treebitmap_nif"
+path = "src/lib.rs"
+crate-type = ["cdylib"]
+
+[dependencies]
+rustler = "0.22.0"
+treebitmap = "0.4.0"
diff --git a/native/treebitmap_nif/README.md b/native/treebitmap_nif/README.md
new file mode 100644
index 0000000..67e961c
--- /dev/null
+++ b/native/treebitmap_nif/README.md
@@ -0,0 +1,20 @@
+# NIF for Elixir.TreeBitmap.NIF
+
+## To build the NIF module:
+
+- Your NIF will now build along with your project.
+
+## To load the NIF:
+
+```elixir
+defmodule TreeBitmap.NIF do
+ use Rustler, otp_app: :tree_bitmap, crate: "treebitmap_nif"
+
+ # When your NIF is loaded, it will override this function.
+ def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
+end
+```
+
+## Examples
+
+[This](https://github.com/hansihe/NifIo) is a complete example of a NIF written in Rust.
diff --git a/native/treebitmap_nif/src/lib.rs b/native/treebitmap_nif/src/lib.rs
new file mode 100644
index 0000000..7ff0a90
--- /dev/null
+++ b/native/treebitmap_nif/src/lib.rs
@@ -0,0 +1,107 @@
+use std::sync::Mutex;
+use rustler::{resource::ResourceArc, NifResult, NifRecord, Encoder, Env, Term, types::atom::Atom, types::tuple::make_tuple};
+//use std::net::Ipv6Addr;
+use std::net::{Ipv4Addr};
+use treebitmap::{IpLookupTable};
+
+struct TableResource {
+ pub table: Mutex<IpLookupTable<Ipv4Addr, u32>>
+}
+
+mod atoms {
+ rustler::atoms! {
+ ok,
+ nil,
+ error
+ }
+}
+
+enum AddrTuple {
+ V4(TupleV4),
+ V6(TupleV6)
+}
+
+#[derive(Debug, NifRecord)]
+#[tag = "inet4"]
+struct TupleV4 {
+ pub a: u8,
+ pub b: u8,
+ pub c: u8,
+ pub d: u8
+}
+
+#[derive(Debug, NifRecord)]
+#[tag = "inet6"]
+struct TupleV6 {
+ pub a1: u16,
+ pub a2: u16,
+ pub a3: u16,
+ pub a4: u16,
+ pub a5: u16,
+ pub a6: u16,
+ pub a7: u16,
+ pub a8: u16
+}
+
+#[rustler::nif]
+fn new() -> NifResult<ResourceArc<TableResource>> {
+ let table = IpLookupTable::new();
+ let resource = ResourceArc::new(TableResource {
+ table: Mutex::new(table)
+ });
+ Ok(resource)
+}
+
+#[rustler::nif]
+fn length(table_resource: ResourceArc<TableResource>) -> NifResult<usize> {
+ let table = table_resource.table.lock().unwrap();
+ Ok(table.len())
+}
+
+#[rustler::nif]
+fn add(
+ table_resource: ResourceArc<TableResource>,
+ ipv4: TupleV4,
+ masklen: u32,
+ value: u32
+) -> NifResult<Atom>{
+ let mut table = table_resource.table.lock().unwrap();
+ let addr = Ipv4Addr::new(ipv4.a, ipv4.b, ipv4.c, ipv4.d);
+ table.insert(addr, masklen, value);
+ Ok(atoms::ok())
+}
+
+#[rustler::nif]
+fn remove(
+ table_resource: ResourceArc<TableResource>,
+ ipv4: TupleV4,
+ masklen: u32
+) -> NifResult<Atom>{
+ let mut table = table_resource.table.lock().unwrap();
+ let addr = Ipv4Addr::new(ipv4.a, ipv4.b, ipv4.c, ipv4.d);
+ table.remove(addr, masklen);
+ Ok(atoms::ok())
+}
+
+#[rustler::nif]
+fn lookup<'a>(
+ env: rustler::Env<'a>,
+ table_resource: ResourceArc<TableResource>,
+ ipv4: TupleV4
+) -> Term {
+ let table = table_resource.table.lock().unwrap();
+ let addr = Ipv4Addr::new(ipv4.a, ipv4.b, ipv4.c, ipv4.d);
+ if let Some((prefix, prefixlen, value)) = table.longest_match(addr) {
+ let addr = prefix.octets();
+ make_tuple(env, &[atoms::ok().encode(env), addr.encode(env), prefixlen.encode(env), value.encode(env)])
+ } else {
+ make_tuple(env, &[atoms::ok().encode(env), atoms::nil().encode(env)])
+ }
+}
+
+rustler::init!("Elixir.TreeBitmap.NIF", [new, length, add, remove, lookup], load = on_load);
+
+fn on_load(env: Env, _info: Term) -> bool {
+ rustler::resource!(TableResource, env);
+ true
+}