Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hansihe committed Jul 20, 2016
0 parents commit 67d6440
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The directory Mix will write compiled artifacts to.
/_build

# If you run "mix test --cover", coverage assets end up here.
/cover

# The directory Mix downloads your dependencies sources to.
/deps

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

/native/io/Cargo.lock
/native/io/target
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# NifIo

This is just an experement, do not use this.
30 changes: 30 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.

# You can configure for your application as:
#
# config :nif_io, key: :value
#
# And access this configuration in your application as:
#
# Application.get_env(:nif_io, :key)
#
# Or configure a 3rd-party app:
#
# config :logger, level: :info
#

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
2 changes: 2 additions & 0 deletions lib/nif_io.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
defmodule NifIo do
end
15 changes: 15 additions & 0 deletions lib/nif_io/native.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule NifIo.Native do
require Rustler

@on_load :load_nif

def load_nif do
Rustler.load_nif("io")
end

defp err, do: throw :nif_not_loaded

def open_read_file(_path), do: err
def read_line(_resource), do: err

end
34 changes: 34 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule NifIo.Mixfile do
use Mix.Project

def project do
[app: :nif_io,
version: "0.1.0",
elixir: "~> 1.3",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
compilers: [:rustler] ++ Mix.compilers,
rustler_crates: ["native/io"],
deps: deps()]
end

# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
[applications: [:logger]]
end

# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type "mix help deps" for more examples and options
defp deps do
[{:rustler, "~> 0.1.0"}]
end
end
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
%{"rustler": {:hex, :rustler, "0.1.0", "d7c7f8afc895882079b627507f912bc362dc9067710d8a267b7d3cb511bf1033", [:mix], []}}
2 changes: 2 additions & 0 deletions native/io/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
14 changes: 14 additions & 0 deletions native/io/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "io"
version = "0.1.0"
authors = ["HansiHE <hansihe@hansihe.com>"]

[lib]
name = "io"
path = "src/lib.rs"
crate-type = ["dylib"]

[dependencies]
rustler = "=0.9.1"
rustler_codegen = "=0.9.1"

52 changes: 52 additions & 0 deletions native/io/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#![feature(plugin)]
#![plugin(rustler_codegen)]

#[macro_use]
extern crate rustler;
use rustler::{NifEnv, NifTerm, NifError, NifDecoder, NifEncoder, NifResult};
use rustler::resource::ResourceCell;

use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::io::BufRead;

rustler_export_nifs!(
"Elixir.NifIo.Native",
[("open_read_file", 1, open_read_file),
("read_line", 1, read_line)],
Some(on_load)
);

#[NifResource]
struct FileReadResource {
pub reader: BufReader<File>,
}

fn on_load(env: &NifEnv, load_info: NifTerm) -> bool {
resource_struct_init!(FileReadResource, env);
true
}

fn open_read_file<'a>(env: &'a NifEnv, args: &Vec<NifTerm>) -> NifResult<NifTerm<'a>> {
let path_str: &str = try!(args[0].decode());
let path = Path::new(path_str);
let file_read = File::open(path).unwrap(); // TODO
let buf_reader = BufReader::new(file_read);

let resource = ResourceCell::new(FileReadResource {
reader: buf_reader,
});

Ok(resource.encode(env))
}

fn read_line<'a>(env: &'a NifEnv, args: &Vec<NifTerm>) -> NifResult<NifTerm<'a>> {
let resource: ResourceCell<FileReadResource> = try!(args[0].decode());
let mut resource_struct = resource.write().unwrap();

let mut ret_string = String::new();
resource_struct.reader.read_line(&mut ret_string).unwrap();

Ok(ret_string.encode(env))
}
8 changes: 8 additions & 0 deletions test/nif_io_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule NifIoTest do
use ExUnit.Case
doctest NifIo

test "the truth" do
assert 1 + 1 == 2
end
end
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()

0 comments on commit 67d6440

Please # to comment.