diff --git a/src/conversion.rs b/src/conversion.rs index addc341..54eccc1 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::ffi::{CStr, CString}; use std::hash::{BuildHasher, Hash}; use std::string::String as StdString; @@ -481,6 +481,56 @@ impl<'lua, K: Ord + FromLua<'lua>, V: FromLua<'lua>> FromLua<'lua> for BTreeMap< } } +impl<'lua, T: Eq + Hash + ToLua<'lua>, S: BuildHasher> ToLua<'lua> for HashSet { + fn to_lua(self, lua: &'lua Lua) -> Result> { + Ok(Value::Table(lua.create_table_from( + self.into_iter().map(|val| (val, true)), + )?)) + } +} + +impl<'lua, T: Eq + Hash + FromLua<'lua>, S: BuildHasher + Default> FromLua<'lua> for HashSet { + fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result { + if let Value::Table(table) = value { + table + .pairs::>() + .map(|res| res.map(|(k, _)| k)) + .collect() + } else { + Err(Error::FromLuaConversionError { + from: value.type_name(), + to: "HashSet", + message: Some("expected table".to_string()), + }) + } + } +} + +impl<'lua, T: Ord + ToLua<'lua>> ToLua<'lua> for BTreeSet { + fn to_lua(self, lua: &'lua Lua) -> Result> { + Ok(Value::Table(lua.create_table_from( + self.into_iter().map(|val| (val, true)), + )?)) + } +} + +impl<'lua, T: Ord + FromLua<'lua>> FromLua<'lua> for BTreeSet { + fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result { + if let Value::Table(table) = value { + table + .pairs::>() + .map(|res| res.map(|(k, _)| k)) + .collect() + } else { + Err(Error::FromLuaConversionError { + from: value.type_name(), + to: "BTreeSet", + message: Some("expected table".to_string()), + }) + } + } +} + impl<'lua, T: ToLua<'lua>> ToLua<'lua> for Option { fn to_lua(self, lua: &'lua Lua) -> Result> { match self {