Skip to content

Commit

Permalink
Add IntoLua/FromLua for OsString/OsStr and PathBuf/Path (#459)
Browse files Browse the repository at this point in the history
  • Loading branch information
psentee authored Oct 6, 2024
1 parent ac315fd commit 6d5e735
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
62 changes: 60 additions & 2 deletions src/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::{CStr, CString};
use std::ffi::{CStr, CString, OsStr, OsString};
use std::hash::{BuildHasher, Hash};
use std::os::raw::c_int;
use std::path::{Path, PathBuf};
use std::string::String as StdString;
use std::{slice, str};

use bstr::{BStr, BString};
use bstr::{BStr, BString, ByteVec};
use num_traits::cast;

use crate::error::{Error, Result};
Expand Down Expand Up @@ -603,6 +604,63 @@ impl IntoLua for &BStr {
}
}

impl IntoLua for OsString {
#[inline]
fn into_lua(self, lua: &Lua) -> Result<Value> {
BString::from(
Vec::from_os_string(self).map_err(|val| Error::ToLuaConversionError {
from: "OsString".into(),
to: "string",
message: Some(format!("Invalid encoding: {:?}", val)),
})?,
)
.into_lua(lua)
}
}

impl FromLua for OsString {
#[inline]
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
let ty = value.type_name();
let bs = BString::from_lua(value, lua)?;
Vec::from(bs)
.into_os_string()
.map_err(|err| Error::FromLuaConversionError {
from: ty,
to: "OsString".into(),
message: Some(format!("{}", err)),
})
}
}

impl IntoLua for &OsStr {
#[inline]
fn into_lua(self, lua: &Lua) -> Result<Value> {
OsString::from(self).into_lua(lua)
}
}

impl IntoLua for PathBuf {
#[inline]
fn into_lua(self, lua: &Lua) -> Result<Value> {
self.into_os_string().into_lua(lua)
}
}

impl FromLua for PathBuf {
#[inline]
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
OsString::from_lua(value, lua).map(PathBuf::from)
}
}

impl IntoLua for &Path {
#[inline]
fn into_lua(self, lua: &Lua) -> Result<Value> {
PathBuf::from(self).into_lua(lua)
}
}

#[inline]
unsafe fn push_bytes_into_stack<T>(this: T, lua: &RawLua) -> Result<()>
where
Expand Down
52 changes: 51 additions & 1 deletion tests/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::{CStr, CString};
use std::ffi::{CStr, CString, OsStr, OsString};
use std::path::{Path, PathBuf};

use bstr::BString;
use maplit::{btreemap, btreeset, hashmap, hashset};
Expand Down Expand Up @@ -397,6 +398,55 @@ fn test_bstring_from_lua_buffer() -> Result<()> {
Ok(())
}

#[test]
fn test_osstring_into_from_lua() -> Result<()> {
let lua = Lua::new();

let s = OsString::from("hello, world");

let v = lua.pack(s.as_os_str())?;
assert!(v.is_string());
assert_eq!(v.as_str().unwrap(), "hello, world");

let v = lua.pack(s)?;
assert!(v.is_string());
assert_eq!(v.as_str().unwrap(), "hello, world");

let s = lua.create_string("hello, world")?;
let bstr = lua.unpack::<OsString>(Value::String(s))?;
assert_eq!(bstr, "hello, world");

let bstr = lua.unpack::<OsString>(Value::Integer(123))?;
assert_eq!(bstr, "123");

let bstr = lua.unpack::<OsString>(Value::Number(-123.55))?;
assert_eq!(bstr, "-123.55");

Ok(())
}

#[test]
fn test_pathbuf_into_from_lua() -> Result<()> {
let lua = Lua::new();

let pb = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let pb_str = pb.to_str().unwrap();

let v = lua.pack(pb.as_path())?;
assert!(v.is_string());
assert_eq!(v.as_str().unwrap(), pb_str);

let v = lua.pack(pb.clone())?;
assert!(v.is_string());
assert_eq!(v.as_str().unwrap(), pb_str);

let s = lua.create_string(pb_str)?;
let bstr = lua.unpack::<PathBuf>(Value::String(s))?;
assert_eq!(bstr, pb);

Ok(())
}

#[test]
fn test_option_into_from_lua() -> Result<()> {
let lua = Lua::new();
Expand Down

0 comments on commit 6d5e735

Please sign in to comment.