From 7b2ba256b963def75ad3e3ecc8359426dbe5752a Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Sun, 31 Mar 2024 18:32:53 +0200 Subject: [PATCH] Implement support for conversions of paths --- rustler/src/types/mod.rs | 1 + rustler/src/types/path.rs | 29 +++++++++++++++++++ rustler_tests/lib/rustler_test.ex | 2 ++ rustler_tests/native/rustler_test/src/lib.rs | 2 ++ .../native/rustler_test/src/test_path.rs | 8 +++++ rustler_tests/test/path_test.exs | 0 6 files changed, 42 insertions(+) create mode 100644 rustler/src/types/path.rs create mode 100644 rustler_tests/native/rustler_test/src/test_path.rs create mode 100644 rustler_tests/test/path_test.exs diff --git a/rustler/src/types/mod.rs b/rustler/src/types/mod.rs index 9a5c78a7..152215e0 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