1use std::num::NonZeroI32;
2
3use crate::{
4 AsLua, LuaRead, LuaTable, Nil, Push, PushGuard, PushInto, PushOne, PushOneInto, ReadResult,
5 Void,
6};
7
8#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct AnyLuaString(pub Vec<u8>);
10
11impl AnyLuaString {
12 pub fn as_bytes(&self) -> &[u8] {
13 self.0.as_slice()
14 }
15}
16
17#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
19pub enum AnyHashableLuaValue {
20 LuaString(String),
22 LuaAnyString(AnyLuaString),
23 LuaNumber(i32),
24 LuaBoolean(bool),
26 LuaArray(Vec<(AnyHashableLuaValue, AnyHashableLuaValue)>),
27 LuaNil,
28
29 LuaOther,
32}
33
34#[derive(Clone, Debug, PartialEq)]
36pub enum AnyLuaValue {
37 LuaString(String),
39 LuaAnyString(AnyLuaString),
40 LuaNumber(f64),
41 LuaBoolean(bool),
43 LuaArray(Vec<(AnyLuaValue, AnyLuaValue)>),
44 LuaNil,
45
46 LuaOther,
49}
50
51macro_rules! impl_any_lua_value {
52 (@push $self:expr, $lua:expr, $push:ident) => {
53 Ok(match $self {
54 Self::LuaString(val) => val.$push($lua),
55 Self::LuaAnyString(val) => val.$push($lua),
56 Self::LuaNumber(val) => val.$push($lua),
57 Self::LuaBoolean(val) => val.$push($lua),
58 Self::LuaArray(val) => val.$push($lua),
59 Self::LuaNil => Nil.$push($lua),
60 Self::LuaOther => panic!("can't push a AnyLuaValue of type Other"),
61 })
62 };
63 ($t:ty) => {
64 impl<L: AsLua> Push<L> for $t {
65 type Err = Void; #[inline]
68 fn push_to_lua(&self, lua: L) -> Result<PushGuard<L>, (Void, L)> {
69 impl_any_lua_value!(@push self, lua, push_no_err)
70 }
71 }
72
73 impl<L: AsLua> PushOne<L> for $t {}
74
75 impl<L: AsLua> PushInto<L> for $t {
76 type Err = Void; #[inline]
79 fn push_into_lua(self, lua: L) -> Result<PushGuard<L>, (Void, L)> {
80 impl_any_lua_value!(@push self, lua, push_into_no_err)
81 }
82 }
83
84 impl<L: AsLua> PushOneInto<L> for $t {}
85
86 impl<L: AsLua> LuaRead<L> for $t {
87 #[inline]
88 fn lua_read_at_position(lua: L, index: NonZeroI32) -> ReadResult<Self, L> {
89 let lua = match LuaRead::lua_read_at_position(lua, index) {
90 Ok(v) => return Ok(Self::LuaString(v)),
91 Err((lua, _)) => lua,
92 };
93
94 let lua = match LuaRead::lua_read_at_position(lua, index) {
95 Ok(v) => return Ok(Self::LuaAnyString(v)),
96 Err((lua, _)) => lua,
97 };
98
99 let lua = match LuaRead::lua_read_at_position(lua, index) {
100 Ok(v) => return Ok(Self::LuaNumber(v)),
101 Err((lua, _)) => lua,
102 };
103
104 let lua = match LuaRead::lua_read_at_position(lua, index) {
105 Ok(v) => return Ok(Self::LuaBoolean(v)),
106 Err((lua, _)) => lua,
107 };
108
109 let lua = match LuaRead::lua_read_at_position(lua, index) {
110 Ok(v) => return Ok(Self::LuaString(v)),
111 Err((lua, _)) => lua,
112 };
113
114 let lua = match LuaRead::lua_read_at_position(lua, index) {
115 Ok(v) => return Ok(Self::LuaAnyString(v)),
116 Err((lua, _)) => lua,
117 };
118
119 let lua = match Nil::lua_read_at_position(lua, index) {
120 Ok(Nil) => return Ok(Self::LuaNil),
121 Err((lua, _)) => lua,
122 };
123
124 let _ = match LuaTable::lua_read_at_position(lua.as_lua(), index) {
125 Ok(v) => return Ok(
126 Self::LuaArray(v.iter::<Self, Self>().flatten().collect())
127 ),
128 Err((lua, _)) => lua,
129 };
130
131 Ok(Self::LuaOther)
132 }
133 }
134 }
135}
136
137impl_any_lua_value! {AnyLuaValue}
138impl_any_lua_value! {AnyHashableLuaValue}