hlua/
lib.rs

1//! High-level zero-cost bindings for Lua
2//!
3//! Lua is an interpreted programming language. This crate allows you to execute Lua code.
4//!
5//! # General usage
6//!
7//! In order to execute Lua code you first need a *Lua context*, which is represented in this
8//! library with [the `Lua` struct](struct.Lua.html). You can then call
9//! [the `execute` method](struct.Lua.html#method.execute) on this object.
10//!
11//! For example:
12//!
13//! ```
14//! use hlua::Lua;
15//!
16//! let mut lua = Lua::new();
17//! lua.execute::<()>("a = 12 * 5").unwrap();
18//! ```
19//!
20//! This example puts the value `60` in the global variable `a`. The values of all global variables
21//! are stored within the `Lua` struct. If you execute multiple Lua scripts on the same context,
22//! each script will have access to the same global variables that were modified by the previous
23//! scripts.
24//!
25//! In order to do something actually useful with Lua, we will need to make Lua and Rust
26//! communicate with each other. This can be done in four ways:
27//!
28//! - You can use methods on the `Lua` struct to read or write the values of global variables with
29//!   the [`get`](struct.Lua.html#method.get) and [`set`](struct.Lua.html#method.set) methods. For
30//!   example you can write to a global variable with a Lua script then read it from Rust, or you
31//!   can write to a global variable from Rust then read it from a Lua script.
32//!
33//! - The Lua script that you execute with the [`execute`](struct.Lua.html#method.execute) method
34//!   can return a value.
35//!
36//! - You can set the value of a global variable to a Rust functions or closures, which can then be
37//!   invoked with a Lua script. See [the `Function` struct](struct.Function.html) for more
38//!   information. For example if you set the value of the global variable `foo` to a Rust
39//!   function, you can then call it from Lua with `foo()`.
40//!
41//! - Similarly you can set the value of a global variable to a Lua function, then call it from
42//!   Rust. The function call can return a value.
43//!
44//! Which method(s) you use depends on which API you wish to expose to your Lua scripts.
45//!
46//! # Pushing and loading values
47//!
48//! The interface between Rust and Lua involves two things:
49//!
50//! - Sending values from Rust to Lua, which is known as *pushing* the value.
51//! - Sending values from Lua to Rust, which is known as *loading* the value.
52//!
53//! Pushing (ie. sending from Rust to Lua) can be done with
54//! [the `set` method](struct.Lua.html#method.set):
55//!
56//! ```
57//! # use hlua::Lua;
58//! # let mut lua = Lua::new();
59//! lua.set("a", 50);
60//! ```
61//!
62//! You can push values that implement [the `Push` trait](trait.Push.html) or
63//! [the `PushOne` trait](trait.PushOne.html) depending on the situation:
64//!
65//! - Integers, floating point numbers and booleans.
66//! - `String` and `&str`.
67//! - Any Rust function or closure whose parameters and loadable and whose return type is pushable.
68//!   See the documentation of [the `Function` struct](struct.Function.html) for more information.
69//! - [The `AnyLuaValue` struct](struct.AnyLuaValue.html). This enumeration represents any possible
70//!   value in Lua.
71//! - The [`LuaCode`](struct.LuaCode.html) and
72//!   [`LuaCodeFromReader`](struct.LuaCodeFromReader.html) structs. Since pushing these structs can
73//!   result in an error, you need to use [`checked_set`](struct.Lua.html#method.checked_set)
74//!   instead of `set`.
75//! - `Vec`s and `HashMap`s whose content is pushable.
76//! - As a special case, `Result` can be pushed only as the return type of a Rust function or
77//!   closure. If they contain an error, the Rust function call is considered to have failed.
78//! - As a special case, tuples can be pushed when they are the return type of a Rust function or
79//!   closure. They implement `Push` but not `PushOne`.
80//! - TODO: userdata
81//!
82//! Loading (ie. sending from Lua to Rust) can be done with
83//! [the `get` method](struct.Lua.html#method.get):
84//!
85//! ```no_run
86//! # use hlua::Lua;
87//! # let mut lua = Lua::new();
88//! let a: i32 = lua.get("a").unwrap();
89//! ```
90//!
91//! You can load values that implement [the `LuaRead` trait](trait.LuaRead.html):
92//!
93//! - Integers, floating point numbers and booleans.
94//! - `String` and [`StringInLua`](struct.StringInLua.html) (ie. the equivalent of `&str`). Loading
95//!   the latter has no cost while loading a `String` performs an allocation.
96//! - Any function (Lua or Rust), with [the `LuaFunction` struct](struct.LuaFunction.html). This
97//!   can then be used to execute the function.
98//! - [The `AnyLuaValue` struct](struct.AnyLuaValue.html). This enumeration represents any possible
99//!   value in Lua.
100//! - [The `LuaTable` struct](struct.LuaTable.html). This struct represents a table in Lua, where
101//!   keys and values can be of different types. The table can then be iterated and individual
102//!   elements can be loaded or modified.
103//! - As a special case, tuples can be loaded when they are the return type of a Lua function or as
104//!   the return type of [`execute`](struct.Lua.html#method.execute).
105//! - TODO: userdata
106//!
107
108// Export the version of lua52_sys in use by this crate. This allows clients to perform low-level
109// Lua operations without worrying about semver.
110#[doc(hidden)]
111pub extern crate lua52_sys as ffi;
112extern crate libc;
113
114use std::ffi::{CStr, CString};
115use std::io::Read;
116use std::io::Error as IoError;
117use std::borrow::Borrow;
118use std::marker::PhantomData;
119use std::error::Error;
120use std::fmt;
121use std::convert::From;
122use std::io;
123
124pub use any::{AnyHashableLuaValue, AnyLuaString, AnyLuaValue};
125pub use functions_write::{Function, InsideCallback};
126pub use functions_write::{function0, function1, function2, function3, function4, function5};
127pub use functions_write::{function6, function7, function8, function9, function10};
128pub use lua_functions::LuaFunction;
129pub use lua_functions::LuaFunctionCallError;
130pub use lua_functions::{LuaCode, LuaCodeFromReader};
131pub use lua_tables::LuaTable;
132pub use lua_tables::LuaTableIterator;
133pub use tuples::TuplePushError;
134pub use userdata::UserdataOnStack;
135pub use userdata::{push_userdata, read_userdata};
136pub use values::StringInLua;
137
138mod any;
139mod functions_write;
140mod lua_functions;
141mod lua_tables;
142mod macros;
143mod rust_tables;
144mod userdata;
145mod values;
146mod tuples;
147
148/// Main object of the library.
149///
150/// The lifetime parameter corresponds to the lifetime of the content of the Lua context.
151///
152/// # About panic safety
153///
154/// This type isn't panic safe. This means that if a panic happens while you were using the `Lua`,
155/// then it will probably stay in a corrupt state. Trying to use the `Lua` again will most likely
156/// result in another panic but shouldn't result in unsafety.
157#[derive(Debug)]
158pub struct Lua<'lua> {
159    lua: LuaContext,
160    must_be_closed: bool,
161    marker: PhantomData<&'lua ()>,
162}
163
164/// RAII guard for a value pushed on the stack.
165///
166/// You shouldn't have to manipulate this type directly unless you are fiddling with the
167/// library's internals.
168#[derive(Debug)]
169pub struct PushGuard<L> {
170    lua: L,
171    size: i32,
172    raw_lua: LuaContext,
173}
174
175impl<'lua, L> PushGuard<L>
176    where L: AsMutLua<'lua>
177{
178    /// Creates a new `PushGuard` from this Lua context representing `size` items on the stack.
179    /// When this `PushGuard` is destroyed, `size` items will be popped.
180    ///
181    /// This is unsafe because the Lua stack can be corrupted if this is misused.
182    #[inline]
183    pub unsafe fn new(mut lua: L, size: i32) -> Self {
184        let raw_lua = lua.as_mut_lua();
185        PushGuard {
186            lua,
187            size,
188            raw_lua,
189        }
190    }
191
192    #[inline]
193    fn assert_one_and_forget(self) -> i32 {
194        assert_eq!(self.size, 1);
195        self.forget_internal()
196    }
197
198    /// Returns the number of elements managed by this `PushGuard`.
199    #[inline]
200    pub fn size(&self) -> i32 {
201        self.size
202    }
203
204    /// Prevents the value from being popped when the `PushGuard` is destroyed, and returns the
205    /// number of elements on the Lua stack.
206    ///
207    /// This is unsafe because the Lua stack can be corrupted if this is misused.
208    #[inline]
209    pub unsafe fn forget(self) -> i32 {
210        self.forget_internal()
211    }
212
213    /// Internal crate-only version of `forget`. It is generally assumed that code within this
214    /// crate that calls this method knows what it is doing.
215    #[inline]
216    fn forget_internal(mut self) -> i32 {
217        let size = self.size;
218        self.size = 0;
219        size
220    }
221
222    /// Destroys the guard, popping the value. Returns the inner part,
223    /// which returns access when using by-value capture.
224    #[inline]
225    pub fn into_inner(mut self) -> L {
226        unsafe {
227            use std::{mem, ptr};
228
229            let mut res;
230            res = mem::MaybeUninit::uninit();
231            ptr::copy_nonoverlapping(&self.lua, res.as_mut_ptr(), 1);
232            if self.size != 0 {
233                ffi::lua_pop(self.lua.as_mut_lua().0, self.size);
234            }
235
236            mem::forget(self);
237
238            res.assume_init()
239        }
240    }
241}
242
243/// Trait for objects that have access to a Lua context. When using a context returned by a
244/// `AsLua`, you are not allowed to modify the stack.
245// TODO: the lifetime should be an associated lifetime instead
246pub unsafe trait AsLua<'lua> {
247    fn as_lua(&self) -> LuaContext;
248}
249
250/// Trait for objects that have access to a Lua context. You are allowed to modify the stack, but
251/// it must be in the same state as it was when you started.
252// TODO: the lifetime should be an associated lifetime instead
253pub unsafe trait AsMutLua<'lua>: AsLua<'lua> {
254    /// Returns the raw Lua context.
255    fn as_mut_lua(&mut self) -> LuaContext;
256}
257
258/// Opaque type that contains the raw Lua context.
259// TODO: probably no longer necessary
260#[derive(Copy, Clone, Debug)]
261pub struct LuaContext(*mut ffi::lua_State);
262
263impl LuaContext {
264    /// Return a pointer to the inner `lua_State` for this context. This is an escape hatch that
265    /// lets the caller perform arbitrary operations against the FFI directly.
266    ///
267    /// Be careful: performing operations on this state might invalidate assumptions made in
268    /// higher-level APIs. For example, pushing a value onto the Lua stack will cause `PushGuard`s
269    /// in Rust code to be out of sync with the Lua stack.
270    #[doc(hidden)]
271    #[inline]
272    pub fn state_ptr(&self) -> *mut ffi::lua_State {
273        self.0
274    }
275}
276
277unsafe impl Send for LuaContext {}
278
279unsafe impl<'a, 'lua> AsLua<'lua> for Lua<'lua> {
280    #[inline]
281    fn as_lua(&self) -> LuaContext {
282        self.lua
283    }
284}
285
286unsafe impl<'lua> AsMutLua<'lua> for Lua<'lua> {
287    #[inline]
288    fn as_mut_lua(&mut self) -> LuaContext {
289        self.lua
290    }
291}
292
293unsafe impl<'lua, L> AsLua<'lua> for PushGuard<L>
294    where L: AsMutLua<'lua>
295{
296    #[inline]
297    fn as_lua(&self) -> LuaContext {
298        self.lua.as_lua()
299    }
300}
301
302unsafe impl<'lua, L> AsMutLua<'lua> for PushGuard<L>
303    where L: AsMutLua<'lua>
304{
305    #[inline]
306    fn as_mut_lua(&mut self) -> LuaContext {
307        self.lua.as_mut_lua()
308    }
309}
310
311unsafe impl<'a, 'lua, L: ?Sized> AsLua<'lua> for &'a L
312    where L: AsLua<'lua>
313{
314    #[inline]
315    fn as_lua(&self) -> LuaContext {
316        (**self).as_lua()
317    }
318}
319
320unsafe impl<'a, 'lua, L: ?Sized> AsLua<'lua> for &'a mut L
321    where L: AsLua<'lua>
322{
323    #[inline]
324    fn as_lua(&self) -> LuaContext {
325        (**self).as_lua()
326    }
327}
328
329unsafe impl<'a, 'lua, L: ?Sized> AsMutLua<'lua> for &'a mut L
330    where L: AsMutLua<'lua>
331{
332    #[inline]
333    fn as_mut_lua(&mut self) -> LuaContext {
334        (**self).as_mut_lua()
335    }
336}
337
338/// Types that can be given to a Lua context, for example with `lua.set()` or as a return value
339/// of a function.
340pub trait Push<L> {
341    /// Error that can happen when pushing a value.
342    type Err;
343
344    /// Pushes the value on the top of the stack.
345    ///
346    /// Must return a guard representing the elements that have been pushed.
347    ///
348    /// You can implement this for any type you want by redirecting to call to
349    /// another implementation (for example `5.push_to_lua`) or by calling
350    /// `userdata::push_userdata`.
351    fn push_to_lua(self, lua: L) -> Result<PushGuard<L>, (Self::Err, L)>;
352
353    /// Same as `push_to_lua` but can only succeed and is only available if `Err` is `Void`.
354    // TODO: when https://github.com/rust-lang/rust/issues/20041 is fixed, use `Self::Err == Void`
355    #[inline]
356    fn push_no_err<E>(self, lua: L) -> PushGuard<L>
357        where Self: Sized,
358              Self: Push<L, Err = E>,
359              E: Into<Void>,
360    {
361        match self.push_to_lua(lua) {
362            Ok(p) => p,
363            Err(_) => unreachable!(),
364        }
365    }
366}
367
368/// Extension trait for `Push`. Guarantees that only one element will be pushed.
369///
370/// This should be implemented on most types that implement `Push`, except for tuples.
371///
372/// > **Note**: Implementing this trait on a type that pushes multiple elements will most likely
373/// > result in panics.
374// Note for the implementation: since this trait is not unsafe, it is mostly a hint. Functions can
375// require this trait if they only accept one pushed element, but they must also add a runtime
376// assertion to make sure that only one element was actually pushed.
377pub trait PushOne<L>: Push<L> {}
378
379/// Type that cannot be instantiated.
380///
381/// Will be replaced with `!` eventually (https://github.com/rust-lang/rust/issues/35121).
382#[derive(Debug, Copy, Clone)]
383pub enum Void {}
384
385impl fmt::Display for Void {
386    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
387        unreachable!("Void cannot be instantiated")
388    }
389}
390
391/// Types that can be obtained from a Lua context.
392///
393/// Most types that implement `Push` also implement `LuaRead`, but this is not always the case
394/// (for example `&'static str` implements `Push` but not `LuaRead`).
395pub trait LuaRead<L>: Sized {
396    /// Reads the data from Lua.
397    #[inline]
398    fn lua_read(lua: L) -> Result<Self, L> {
399        LuaRead::lua_read_at_position(lua, -1)
400    }
401
402    /// Reads the data from Lua at a given position.
403    fn lua_read_at_position(lua: L, index: i32) -> Result<Self, L>;
404}
405
406/// Error that can happen when executing Lua code.
407#[derive(Debug)]
408pub enum LuaError {
409    /// There was a syntax error when parsing the Lua code.
410    SyntaxError(String),
411
412    /// There was an error during execution of the Lua code
413    /// (for example not enough parameters for a function call).
414    ExecutionError(String),
415
416    /// There was an IoError while reading the source code to execute.
417    ReadError(IoError),
418
419    /// The call to `execute` has requested the wrong type of data.
420    WrongType,
421}
422
423impl fmt::Display for LuaError {
424    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
425        use LuaError::*;
426
427        match *self {
428            SyntaxError(ref s) => write!(f, "Syntax error: {}", s),
429            ExecutionError(ref s) => write!(f, "Execution error: {}", s),
430            ReadError(ref e) => write!(f, "Read error: {}", e),
431            WrongType => write!(f, "Wrong type returned by Lua"),
432        }
433    }
434}
435
436impl Error for LuaError {
437    fn description(&self) -> &str {
438        use LuaError::*;
439
440        match *self {
441            SyntaxError(ref s) => &s,
442            ExecutionError(ref s) => &s,
443            ReadError(_) => "read error",
444            WrongType => "wrong type returned by Lua",
445        }
446    }
447
448    fn cause(&self) -> Option<&Error> {
449        use LuaError::*;
450
451        match *self {
452            SyntaxError(_) => None,
453            ExecutionError(_) => None,
454            ReadError(ref e) => Some(e),
455            WrongType => None,
456        }
457    }
458}
459
460impl From<io::Error> for LuaError {
461    fn from(e: io::Error) -> Self {
462        LuaError::ReadError(e)
463    }
464}
465
466impl<'lua> Lua<'lua> {
467    /// Builds a new empty Lua context.
468    ///
469    /// There are no global variables and the registry is totally empty. Even the functions from
470    /// the standard library can't be used.
471    ///
472    /// If you want to use the Lua standard library in the scripts of this context, see
473    /// [the openlibs method](#method.openlibs)
474    ///
475    /// # Example
476    ///
477    /// ```
478    /// use hlua::Lua;
479    /// let mut lua = Lua::new();
480    /// ```
481    ///
482    /// # Panic
483    ///
484    /// The function panics if the underlying call to `lua_newstate` fails
485    /// (which indicates lack of memory).
486    #[inline]
487    pub fn new() -> Lua<'lua> {
488        let lua = unsafe { ffi::lua_newstate(alloc, std::ptr::null_mut()) };
489        if lua.is_null() {
490            panic!("lua_newstate failed");
491        }
492
493        // this alloc function is required to create a lua state.
494        extern "C" fn alloc(_ud: *mut libc::c_void,
495                            ptr: *mut libc::c_void,
496                            _osize: libc::size_t,
497                            nsize: libc::size_t)
498                            -> *mut libc::c_void {
499            unsafe {
500                if nsize == 0 {
501                    libc::free(ptr as *mut libc::c_void);
502                    std::ptr::null_mut()
503                } else {
504                    libc::realloc(ptr, nsize)
505                }
506            }
507        }
508
509        // called whenever lua encounters an unexpected error.
510        extern "C" fn panic(lua: *mut ffi::lua_State) -> libc::c_int {
511            let err = unsafe { ffi::lua_tostring(lua, -1) };
512            let err = unsafe { CStr::from_ptr(err) };
513            let err = String::from_utf8(err.to_bytes().to_vec()).unwrap();
514            panic!("PANIC: unprotected error in call to Lua API ({})\n", err);
515        }
516
517        unsafe { ffi::lua_atpanic(lua, panic) };
518
519        Lua {
520            lua: LuaContext(lua),
521            must_be_closed: true,
522            marker: PhantomData,
523        }
524    }
525
526    /// Takes an existing `lua_State` and build a Lua object from it.
527    ///
528    /// If `close_at_the_end` is true, `lua_close` will be called on the `lua_State` in the
529    /// destructor.
530    #[inline]
531    pub unsafe fn from_existing_state<T>(lua: *mut T, close_at_the_end: bool) -> Lua<'lua> {
532        Lua {
533            lua: std::mem::transmute(lua),
534            must_be_closed: close_at_the_end,
535            marker: PhantomData,
536        }
537    }
538
539    /// Opens all standard Lua libraries.
540    ///
541    /// See the reference for the standard library here:
542    /// https://www.lua.org/manual/5.2/manual.html#6
543    ///
544    /// This is done by calling `luaL_openlibs`.
545    ///
546    /// # Example
547    ///
548    /// ```
549    /// use hlua::Lua;
550    /// let mut lua = Lua::new();
551    /// lua.openlibs();
552    /// ```
553    #[inline]
554    pub fn openlibs(&mut self) {
555        unsafe { ffi::luaL_openlibs(self.lua.0) }
556    }
557
558    /// Opens base library.
559    ///
560    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_base
561    #[inline]
562    pub fn open_base(&mut self) {
563        unsafe { ffi::luaopen_base(self.lua.0) }
564    }
565
566    /// Opens bit32 library.
567    ///
568    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_bit32
569    #[inline]
570    pub fn open_bit32(&mut self) {
571        unsafe { ffi::luaopen_bit32(self.lua.0) }
572    }
573
574    /// Opens coroutine library.
575    ///
576    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_coroutine
577    #[inline]
578    pub fn open_coroutine(&mut self) {
579        unsafe { ffi::luaopen_coroutine(self.lua.0) }
580    }
581
582    /// Opens debug library.
583    ///
584    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_debug
585    #[inline]
586    pub fn open_debug(&mut self) {
587        unsafe { ffi::luaopen_debug(self.lua.0) }
588    }
589
590    /// Opens io library.
591    ///
592    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_io
593    #[inline]
594    pub fn open_io(&mut self) {
595        unsafe { ffi::luaopen_io(self.lua.0) }
596    }
597
598    /// Opens math library.
599    ///
600    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_math
601    #[inline]
602    pub fn open_math(&mut self) {
603        unsafe { ffi::luaopen_math(self.lua.0) }
604    }
605
606    /// Opens os library.
607    ///
608    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_os
609    #[inline]
610    pub fn open_os(&mut self) {
611        unsafe { ffi::luaopen_os(self.lua.0) }
612    }
613
614    /// Opens package library.
615    ///
616    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_package
617    #[inline]
618    pub fn open_package(&mut self) {
619        unsafe { ffi::luaopen_package(self.lua.0) }
620    }
621
622    /// Opens string library.
623    ///
624    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_string
625    #[inline]
626    pub fn open_string(&mut self) {
627        unsafe { ffi::luaopen_string(self.lua.0) }
628    }
629
630    /// Opens table library.
631    ///
632    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_table
633    #[inline]
634    pub fn open_table(&mut self) {
635        unsafe { ffi::luaopen_table(self.lua.0) }
636    }
637
638    /// Executes some Lua code in the context.
639    ///
640    /// The code will have access to all the global variables you set with methods such as `set`.
641    /// Every time you execute some code in the context, the code can modify these global variables.
642    ///
643    /// The template parameter of this function is the return type of the expression that is being
644    /// evaluated.
645    /// In order to avoid compilation error, you should call this function either by doing
646    /// `lua.execute::<T>(...)` or `let result: T = lua.execute(...);` where `T` is the type of
647    /// the expression.
648    /// The function will return an error if the actual return type of the expression doesn't
649    /// match the template parameter.
650    ///
651    /// The return type must implement the `LuaRead` trait. See
652    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
653    /// information.
654    ///
655    /// # Examples
656    ///
657    /// Without a return value:
658    ///
659    /// ```
660    /// use hlua::Lua;
661    /// let mut lua = Lua::new();
662    /// lua.execute::<()>("function multiply_by_two(a) return a * 2 end").unwrap();
663    /// lua.execute::<()>("twelve = multiply_by_two(6)").unwrap();
664    /// ```
665    ///
666    /// With a return value:
667    ///
668    /// ```
669    /// use hlua::Lua;
670    /// let mut lua = Lua::new();
671    ///
672    /// let twelve: i32 = lua.execute("return 3 * 4;").unwrap();
673    /// let sixty = lua.execute::<i32>("return 6 * 10;").unwrap();
674    /// ```
675    #[inline]
676    pub fn execute<'a, T>(&'a mut self, code: &str) -> Result<T, LuaError>
677        where T: for<'g> LuaRead<PushGuard<&'g mut PushGuard<&'a mut Lua<'lua>>>>
678    {
679        let mut f = try!(lua_functions::LuaFunction::load(self, code));
680        f.call()
681    }
682
683    /// Executes some Lua code on the context.
684    ///
685    /// This does the same thing as [the `execute` method](#method.execute), but the code to
686    /// execute is loaded from an object that implements `Read`.
687    ///
688    /// Use this method when you potentially have a large amount of code (for example if you read
689    /// the code from a file) in order to avoid having to put everything in memory first before
690    /// passing it to the Lua interpreter.
691    ///
692    /// # Example
693    ///
694    /// ```no_run
695    /// use std::fs::File;
696    /// use hlua::Lua;
697    ///
698    /// let mut lua = Lua::new();
699    /// let script = File::open("script.lua").unwrap();
700    /// lua.execute_from_reader::<(), _>(script).unwrap();
701    /// ```
702    #[inline]
703    pub fn execute_from_reader<'a, T, R>(&'a mut self, code: R) -> Result<T, LuaError>
704        where T: for<'g> LuaRead<PushGuard<&'g mut PushGuard<&'a mut Lua<'lua>>>>,
705              R: Read
706    {
707        let mut f = try!(lua_functions::LuaFunction::load_from_reader(self, code));
708        f.call()
709    }
710
711    /// Reads the value of a global variable.
712    ///
713    /// Returns `None` if the variable doesn't exist or has the wrong type.
714    ///
715    /// The type must implement the `LuaRead` trait. See
716    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
717    /// information.
718    ///
719    /// # Example
720    ///
721    /// ```
722    /// use hlua::Lua;
723    /// let mut lua = Lua::new();
724    /// lua.execute::<()>("a = 5").unwrap();
725    /// let a: i32 = lua.get("a").unwrap();
726    /// assert_eq!(a, 5);
727    /// ```
728    #[inline]
729    pub fn get<'l, V, I>(&'l mut self, index: I) -> Option<V>
730        where I: Borrow<str>,
731              V: LuaRead<PushGuard<&'l mut Lua<'lua>>>
732    {
733        let index = CString::new(index.borrow()).unwrap();
734        unsafe {
735            ffi::lua_getglobal(self.lua.0, index.as_ptr());
736        }
737        if unsafe { ffi::lua_isnil(self.as_lua().0, -1) } {
738            let raw_lua = self.as_lua();
739            let _guard = PushGuard {
740                lua: self,
741                size: 1,
742                raw_lua: raw_lua,
743            };
744            return None;
745        }
746        let raw_lua = self.as_lua();
747        let guard = PushGuard {
748            lua: self,
749            size: 1,
750            raw_lua: raw_lua,
751        };
752        LuaRead::lua_read(guard).ok()
753    }
754
755    /// Reads the value of a global, capturing the context by value.
756    #[inline]
757    pub fn into_get<V, I>(self, index: I) -> Result<V, PushGuard<Self>>
758        where I: Borrow<str>,
759              V: LuaRead<PushGuard<Lua<'lua>>>
760    {
761        let index = CString::new(index.borrow()).unwrap();
762        unsafe {
763            ffi::lua_getglobal(self.lua.0, index.as_ptr());
764        }
765        let is_nil = unsafe { ffi::lua_isnil(self.as_lua().0, -1) };
766        let raw_lua = self.as_lua();
767        let guard = PushGuard {
768            lua: self,
769            size: 1,
770            raw_lua: raw_lua,
771        };
772        if is_nil {
773            Err(guard)
774        } else {
775            LuaRead::lua_read(guard)
776        }
777    }
778
779    /// Modifies the value of a global variable.
780    ///
781    /// If you want to write an array, you are encouraged to use
782    /// [the `empty_array` method](#method.empty_array) instead.
783    ///
784    /// The type must implement the `PushOne` trait. See
785    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
786    /// information.
787    ///
788    /// # Example
789    ///
790    /// ```
791    /// use hlua::Lua;
792    /// let mut lua = Lua::new();
793    ///
794    /// lua.set("a", 12);
795    /// let six: i32 = lua.execute("return a / 2;").unwrap();
796    /// assert_eq!(six, 6);
797    /// ```
798    #[inline]
799    pub fn set<I, V, E>(&mut self, index: I, value: V)
800        where I: Borrow<str>,
801              for<'a> V: PushOne<&'a mut Lua<'lua>, Err = E>,
802              E: Into<Void>,
803    {
804        match self.checked_set(index, value) {
805            Ok(_) => (),
806            Err(_) => unreachable!(),
807        }
808    }
809
810    /// Modifies the value of a global variable.
811    // TODO: docs
812    #[inline]
813    pub fn checked_set<I, V, E>(&mut self, index: I, value: V) -> Result<(), E>
814        where I: Borrow<str>,
815              for<'a> V: PushOne<&'a mut Lua<'lua>, Err = E>
816    {
817        unsafe {
818            // TODO: can be simplified
819            let mut me = self;
820            ffi::lua_pushglobaltable(me.lua.0);
821            match index.borrow().push_to_lua(&mut me) {
822                Ok(pushed) => {
823                    debug_assert_eq!(pushed.size, 1);
824                    pushed.forget()
825                }
826                Err(_) => unreachable!(),
827            };
828            match value.push_to_lua(&mut me) {
829                Ok(pushed) => {
830                    assert_eq!(pushed.size, 1);
831                    pushed.forget()
832                }
833                Err((err, lua)) => {
834                    ffi::lua_pop(lua.lua.0, 2);
835                    return Err(err);
836                }
837            };
838            ffi::lua_settable(me.lua.0, -3);
839            ffi::lua_pop(me.lua.0, 1);
840            Ok(())
841        }
842    }
843
844    /// Sets the value of a global variable to an empty array, then loads it.
845    ///
846    /// This is the function you should use if you want to set the value of a global variable to
847    /// an array. After calling it, you will obtain a `LuaTable` object which you can then fill
848    /// with the elements of the array.
849    ///
850    /// # Example
851    ///
852    /// ```
853    /// use hlua::Lua;
854    /// let mut lua = Lua::new();
855    /// lua.openlibs();     // Necessary for `ipairs`.
856    ///
857    /// {
858    ///     let mut array = lua.empty_array("my_values");
859    ///     array.set(1, 10);       // Don't forget that Lua arrays are indexed from 1.
860    ///     array.set(2, 15);
861    ///     array.set(3, 20);
862    /// }
863    ///
864    /// let sum: i32 = lua.execute(r#"
865    ///     local sum = 0
866    ///     for i, val in ipairs(my_values) do
867    ///         sum = sum + val
868    ///     end
869    ///     return sum
870    /// "#).unwrap();
871    ///
872    /// assert_eq!(sum, 45);
873    /// ```
874    #[inline]
875    pub fn empty_array<'a, I>(&'a mut self, index: I) -> LuaTable<PushGuard<&'a mut Lua<'lua>>>
876        where I: Borrow<str>
877    {
878        unsafe {
879            let mut me = self;
880            ffi::lua_pushglobaltable(me.lua.0);
881            match index.borrow().push_to_lua(&mut me) {
882                Ok(pushed) => pushed.forget(),
883                Err(_) => unreachable!(),
884            };
885            ffi::lua_newtable(me.lua.0);
886            ffi::lua_settable(me.lua.0, -3);
887            ffi::lua_pop(me.lua.0, 1);
888
889            // TODO: cleaner implementation
890            me.get(index).unwrap()
891        }
892    }
893
894    /// Loads the array containing the global variables.
895    ///
896    /// In lua, the global variables accessible from the lua code are all part of a table which
897    /// you can load here.
898    ///
899    /// # Examples
900    ///
901    /// The function can be used to write global variables, just like `set`.
902    ///
903    /// ```
904    /// use hlua::Lua;
905    /// let mut lua = Lua::new();
906    /// lua.globals_table().set("a", 5);
907    /// assert_eq!(lua.get::<i32, _>("a"), Some(5));
908    /// ```
909    ///
910    /// A more useful feature for this function is that it allows you to set the metatable of the
911    /// global variables. See TODO for more info.
912    ///
913    /// ```
914    /// use hlua::Lua;
915    /// use hlua::AnyLuaValue;
916    ///
917    /// let mut lua = Lua::new();
918    /// {
919    ///     let mut metatable = lua.globals_table().get_or_create_metatable();
920    ///     metatable.set("__index", hlua::function2(|_: AnyLuaValue, var: String| -> AnyLuaValue {
921    ///         println!("The user tried to access the variable {:?}", var);
922    ///         AnyLuaValue::LuaNumber(48.0)
923    ///     }));
924    /// }
925    ///
926    /// let b: i32 = lua.execute("return b * 2;").unwrap();
927    /// // -> The user tried to access the variable "b"
928    ///
929    /// assert_eq!(b, 96);
930    /// ```
931    #[inline]
932    pub fn globals_table<'a>(&'a mut self) -> LuaTable<PushGuard<&'a mut Lua<'lua>>> {
933        unsafe {
934            ffi::lua_pushglobaltable(self.lua.0);
935        }
936        let raw_lua = self.as_lua();
937        let guard = PushGuard {
938            lua: self,
939            size: 1,
940            raw_lua: raw_lua,
941        };
942        LuaRead::lua_read(guard).ok().unwrap()
943    }
944}
945
946impl<'lua> Drop for Lua<'lua> {
947    #[inline]
948    fn drop(&mut self) {
949        if self.must_be_closed {
950            unsafe { ffi::lua_close(self.lua.0) }
951        }
952    }
953}
954
955impl<L> Drop for PushGuard<L> {
956    #[inline]
957    fn drop(&mut self) {
958        if self.size != 0 {
959            unsafe {
960                ffi::lua_pop(self.raw_lua.0, self.size);
961            }
962        }
963    }
964}
965
966#[cfg(test)]
967mod tests {
968    use Lua;
969    use LuaError;
970
971    #[test]
972    fn open_base_opens_base_library() {
973        let mut lua = Lua::new();
974        match lua.execute::<()>("return assert(true)") {
975            Err(LuaError::ExecutionError(_)) => { },
976            Err(_) => panic!("Wrong error"),
977            Ok(_) => panic!("Unexpected success"),
978        }
979        lua.open_base();
980        let result: bool = lua.execute("return assert(true)").unwrap();
981        assert_eq!(result, true);
982    }
983
984    #[test]
985    fn opening_all_libraries_doesnt_panic() {
986        let mut lua = Lua::new();
987        lua.open_base();
988        lua.open_bit32();
989        lua.open_coroutine();
990        lua.open_debug();
991        lua.open_io();
992        lua.open_math();
993        lua.open_os();
994        lua.open_package();
995        lua.open_string();
996        lua.open_table();
997    }
998}