Skip to content

Commit 6d5e735

Browse files
authored
Add IntoLua/FromLua for OsString/OsStr and PathBuf/Path (#459)
1 parent ac315fd commit 6d5e735

File tree

2 files changed

+111
-3
lines changed

2 files changed

+111
-3
lines changed

src/conversion.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use std::borrow::Cow;
22
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
3-
use std::ffi::{CStr, CString};
3+
use std::ffi::{CStr, CString, OsStr, OsString};
44
use std::hash::{BuildHasher, Hash};
55
use std::os::raw::c_int;
6+
use std::path::{Path, PathBuf};
67
use std::string::String as StdString;
78
use std::{slice, str};
89

9-
use bstr::{BStr, BString};
10+
use bstr::{BStr, BString, ByteVec};
1011
use num_traits::cast;
1112

1213
use crate::error::{Error, Result};
@@ -603,6 +604,63 @@ impl IntoLua for &BStr {
603604
}
604605
}
605606

607+
impl IntoLua for OsString {
608+
#[inline]
609+
fn into_lua(self, lua: &Lua) -> Result<Value> {
610+
BString::from(
611+
Vec::from_os_string(self).map_err(|val| Error::ToLuaConversionError {
612+
from: "OsString".into(),
613+
to: "string",
614+
message: Some(format!("Invalid encoding: {:?}", val)),
615+
})?,
616+
)
617+
.into_lua(lua)
618+
}
619+
}
620+
621+
impl FromLua for OsString {
622+
#[inline]
623+
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
624+
let ty = value.type_name();
625+
let bs = BString::from_lua(value, lua)?;
626+
Vec::from(bs)
627+
.into_os_string()
628+
.map_err(|err| Error::FromLuaConversionError {
629+
from: ty,
630+
to: "OsString".into(),
631+
message: Some(format!("{}", err)),
632+
})
633+
}
634+
}
635+
636+
impl IntoLua for &OsStr {
637+
#[inline]
638+
fn into_lua(self, lua: &Lua) -> Result<Value> {
639+
OsString::from(self).into_lua(lua)
640+
}
641+
}
642+
643+
impl IntoLua for PathBuf {
644+
#[inline]
645+
fn into_lua(self, lua: &Lua) -> Result<Value> {
646+
self.into_os_string().into_lua(lua)
647+
}
648+
}
649+
650+
impl FromLua for PathBuf {
651+
#[inline]
652+
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
653+
OsString::from_lua(value, lua).map(PathBuf::from)
654+
}
655+
}
656+
657+
impl IntoLua for &Path {
658+
#[inline]
659+
fn into_lua(self, lua: &Lua) -> Result<Value> {
660+
PathBuf::from(self).into_lua(lua)
661+
}
662+
}
663+
606664
#[inline]
607665
unsafe fn push_bytes_into_stack<T>(this: T, lua: &RawLua) -> Result<()>
608666
where

tests/conversion.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::borrow::Cow;
22
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
3-
use std::ffi::{CStr, CString};
3+
use std::ffi::{CStr, CString, OsStr, OsString};
4+
use std::path::{Path, PathBuf};
45

56
use bstr::BString;
67
use maplit::{btreemap, btreeset, hashmap, hashset};
@@ -397,6 +398,55 @@ fn test_bstring_from_lua_buffer() -> Result<()> {
397398
Ok(())
398399
}
399400

401+
#[test]
402+
fn test_osstring_into_from_lua() -> Result<()> {
403+
let lua = Lua::new();
404+
405+
let s = OsString::from("hello, world");
406+
407+
let v = lua.pack(s.as_os_str())?;
408+
assert!(v.is_string());
409+
assert_eq!(v.as_str().unwrap(), "hello, world");
410+
411+
let v = lua.pack(s)?;
412+
assert!(v.is_string());
413+
assert_eq!(v.as_str().unwrap(), "hello, world");
414+
415+
let s = lua.create_string("hello, world")?;
416+
let bstr = lua.unpack::<OsString>(Value::String(s))?;
417+
assert_eq!(bstr, "hello, world");
418+
419+
let bstr = lua.unpack::<OsString>(Value::Integer(123))?;
420+
assert_eq!(bstr, "123");
421+
422+
let bstr = lua.unpack::<OsString>(Value::Number(-123.55))?;
423+
assert_eq!(bstr, "-123.55");
424+
425+
Ok(())
426+
}
427+
428+
#[test]
429+
fn test_pathbuf_into_from_lua() -> Result<()> {
430+
let lua = Lua::new();
431+
432+
let pb = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
433+
let pb_str = pb.to_str().unwrap();
434+
435+
let v = lua.pack(pb.as_path())?;
436+
assert!(v.is_string());
437+
assert_eq!(v.as_str().unwrap(), pb_str);
438+
439+
let v = lua.pack(pb.clone())?;
440+
assert!(v.is_string());
441+
assert_eq!(v.as_str().unwrap(), pb_str);
442+
443+
let s = lua.create_string(pb_str)?;
444+
let bstr = lua.unpack::<PathBuf>(Value::String(s))?;
445+
assert_eq!(bstr, pb);
446+
447+
Ok(())
448+
}
449+
400450
#[test]
401451
fn test_option_into_from_lua() -> Result<()> {
402452
let lua = Lua::new();

0 commit comments

Comments
 (0)