diff --git a/rustler/src/types/mod.rs b/rustler/src/types/mod.rs index f5eb0cc6..e43a1c7e 100644 --- a/rustler/src/types/mod.rs +++ b/rustler/src/types/mod.rs @@ -3,6 +3,7 @@ use crate::{Env, Error, NifResult, Term}; #[macro_use] pub mod atom; pub mod i128; +pub mod path; pub use crate::types::atom::Atom; pub mod binary; diff --git a/rustler/src/types/path.rs b/rustler/src/types/path.rs new file mode 100644 index 00000000..c399ec74 --- /dev/null +++ b/rustler/src/types/path.rs @@ -0,0 +1,29 @@ +use crate::{Decoder, Encoder, Env, Error, NifResult, Term}; +use std::path::{Path, PathBuf}; + +impl Encoder for Path { + fn encode<'a>(&self, env: Env<'a>) -> Term<'a> { + self.as_os_str().to_str().encode(env) + } +} + +impl Encoder for PathBuf { + fn encode<'a>(&self, env: Env<'a>) -> Term<'a> { + self.as_path().encode(env) + } +} + +impl<'a> Decoder<'a> for &'a Path { + fn decode(term: Term<'a>) -> NifResult { + let bin = term.decode_as_binary().or(Err(Error::BadArg))?; + let s = std::str::from_utf8(bin.as_slice()).or(Err(Error::BadArg))?; + Ok(Path::new(s)) + } +} + +impl<'a> Decoder<'a> for PathBuf { + fn decode(term: Term<'a>) -> NifResult { + let s: &str = term.decode()?; + Ok(PathBuf::from(s)) + } +} diff --git a/rustler_tests/lib/rustler_test.ex b/rustler_tests/lib/rustler_test.ex index 32326d7a..73d3a82e 100644 --- a/rustler_tests/lib/rustler_test.ex +++ b/rustler_tests/lib/rustler_test.ex @@ -133,4 +133,6 @@ defmodule RustlerTest do def maybe_add_one_to_tuple(_tuple), do: err() def add_i32_from_tuple(_tuple), do: err() def greeting_person_from_tuple(_tuple), do: err() + + def append_to_path(_path, _to_append), do: err() end diff --git a/rustler_tests/native/rustler_test/src/lib.rs b/rustler_tests/native/rustler_test/src/lib.rs index 7faa7115..2a7d7e90 100644 --- a/rustler_tests/native/rustler_test/src/lib.rs +++ b/rustler_tests/native/rustler_test/src/lib.rs @@ -7,6 +7,7 @@ mod test_error; mod test_list; mod test_map; mod test_nif_attrs; +mod test_path; mod test_primitives; mod test_range; mod test_resource; @@ -103,6 +104,7 @@ rustler::init!( test_codegen::reserved_keywords::reserved_keywords_type_echo, test_codegen::generic_types::generic_struct_echo, test_codegen::generic_types::mk_generic_map, + test_path::append_to_path, ], load = load ); diff --git a/rustler_tests/native/rustler_test/src/test_path.rs b/rustler_tests/native/rustler_test/src/test_path.rs new file mode 100644 index 00000000..8f7debc4 --- /dev/null +++ b/rustler_tests/native/rustler_test/src/test_path.rs @@ -0,0 +1,8 @@ +use std::path::{Path, PathBuf}; + +#[rustler::nif] +pub fn append_to_path(p: &Path, comp: &str) -> PathBuf { + let mut p = p.to_path_buf(); + p.push(comp); + p +} diff --git a/rustler_tests/test/path_test.exs b/rustler_tests/test/path_test.exs new file mode 100644 index 00000000..e69de29b