hlua_badtouch/
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        use std::{mem, ptr};
227
228        let mut res;
229        unsafe {
230            res = mem::uninitialized();
231            ptr::copy_nonoverlapping(&self.lua, &mut res, 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
239    }
240}
241
242/// Trait for objects that have access to a Lua context. When using a context returned by a
243/// `AsLua`, you are not allowed to modify the stack.
244// TODO: the lifetime should be an associated lifetime instead
245pub unsafe trait AsLua<'lua> {
246    fn as_lua(&self) -> LuaContext;
247}
248
249/// Trait for objects that have access to a Lua context. You are allowed to modify the stack, but
250/// it must be in the same state as it was when you started.
251// TODO: the lifetime should be an associated lifetime instead
252pub unsafe trait AsMutLua<'lua>: AsLua<'lua> {
253    /// Returns the raw Lua context.
254    fn as_mut_lua(&mut self) -> LuaContext;
255}
256
257/// Opaque type that contains the raw Lua context.
258// TODO: probably no longer necessary
259#[derive(Copy, Clone, Debug)]
260pub struct LuaContext(*mut ffi::lua_State);
261
262impl LuaContext {
263    /// Return a pointer to the inner `lua_State` for this context. This is an escape hatch that
264    /// lets the caller perform arbitrary operations against the FFI directly.
265    ///
266    /// Be careful: performing operations on this state might invalidate assumptions made in
267    /// higher-level APIs. For example, pushing a value onto the Lua stack will cause `PushGuard`s
268    /// in Rust code to be out of sync with the Lua stack.
269    #[doc(hidden)]
270    #[inline]
271    pub fn state_ptr(&self) -> *mut ffi::lua_State {
272        self.0
273    }
274}
275
276unsafe impl Send for LuaContext {}
277
278unsafe impl<'a, 'lua> AsLua<'lua> for Lua<'lua> {
279    #[inline]
280    fn as_lua(&self) -> LuaContext {
281        self.lua
282    }
283}
284
285unsafe impl<'lua> AsMutLua<'lua> for Lua<'lua> {
286    #[inline]
287    fn as_mut_lua(&mut self) -> LuaContext {
288        self.lua
289    }
290}
291
292unsafe impl<'lua, L> AsLua<'lua> for PushGuard<L>
293    where L: AsMutLua<'lua>
294{
295    #[inline]
296    fn as_lua(&self) -> LuaContext {
297        self.lua.as_lua()
298    }
299}
300
301unsafe impl<'lua, L> AsMutLua<'lua> for PushGuard<L>
302    where L: AsMutLua<'lua>
303{
304    #[inline]
305    fn as_mut_lua(&mut self) -> LuaContext {
306        self.lua.as_mut_lua()
307    }
308}
309
310unsafe impl<'a, 'lua, L: ?Sized> AsLua<'lua> for &'a L
311    where L: AsLua<'lua>
312{
313    #[inline]
314    fn as_lua(&self) -> LuaContext {
315        (**self).as_lua()
316    }
317}
318
319unsafe impl<'a, 'lua, L: ?Sized> AsLua<'lua> for &'a mut L
320    where L: AsLua<'lua>
321{
322    #[inline]
323    fn as_lua(&self) -> LuaContext {
324        (**self).as_lua()
325    }
326}
327
328unsafe impl<'a, 'lua, L: ?Sized> AsMutLua<'lua> for &'a mut L
329    where L: AsMutLua<'lua>
330{
331    #[inline]
332    fn as_mut_lua(&mut self) -> LuaContext {
333        (**self).as_mut_lua()
334    }
335}
336
337/// Types that can be given to a Lua context, for example with `lua.set()` or as a return value
338/// of a function.
339pub trait Push<L> {
340    /// Error that can happen when pushing a value.
341    type Err;
342
343    /// Pushes the value on the top of the stack.
344    ///
345    /// Must return a guard representing the elements that have been pushed.
346    ///
347    /// You can implement this for any type you want by redirecting to call to
348    /// another implementation (for example `5.push_to_lua`) or by calling
349    /// `userdata::push_userdata`.
350    fn push_to_lua(self, lua: L) -> Result<PushGuard<L>, (Self::Err, L)>;
351
352    /// Same as `push_to_lua` but can only succeed and is only available if `Err` is `Void`.
353    // TODO: when https://github.com/rust-lang/rust/issues/20041 is fixed, use `Self::Err == Void`
354    #[inline]
355    fn push_no_err<E>(self, lua: L) -> PushGuard<L>
356        where Self: Sized,
357              Self: Push<L, Err = E>,
358              E: Into<Void>,
359    {
360        match self.push_to_lua(lua) {
361            Ok(p) => p,
362            Err(_) => unreachable!(),
363        }
364    }
365}
366
367/// Extension trait for `Push`. Guarantees that only one element will be pushed.
368///
369/// This should be implemented on most types that implement `Push`, except for tuples.
370///
371/// > **Note**: Implementing this trait on a type that pushes multiple elements will most likely
372/// > result in panics.
373// Note for the implementation: since this trait is not unsafe, it is mostly a hint. Functions can
374// require this trait if they only accept one pushed element, but they must also add a runtime
375// assertion to make sure that only one element was actually pushed.
376pub trait PushOne<L>: Push<L> {}
377
378/// Type that cannot be instantiated.
379///
380/// Will be replaced with `!` eventually (https://github.com/rust-lang/rust/issues/35121).
381#[derive(Debug, Copy, Clone)]
382pub enum Void {}
383
384impl fmt::Display for Void {
385    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
386        unreachable!("Void cannot be instantiated")
387    }
388}
389
390/// Types that can be obtained from a Lua context.
391///
392/// Most types that implement `Push` also implement `LuaRead`, but this is not always the case
393/// (for example `&'static str` implements `Push` but not `LuaRead`).
394pub trait LuaRead<L>: Sized {
395    /// Reads the data from Lua.
396    #[inline]
397    fn lua_read(lua: L) -> Result<Self, L> {
398        LuaRead::lua_read_at_position(lua, -1)
399    }
400
401    /// Reads the data from Lua at a given position.
402    fn lua_read_at_position(lua: L, index: i32) -> Result<Self, L>;
403}
404
405/// Error that can happen when executing Lua code.
406#[derive(Debug)]
407pub enum LuaError {
408    /// There was a syntax error when parsing the Lua code.
409    SyntaxError(String),
410
411    /// There was an error during execution of the Lua code
412    /// (for example not enough parameters for a function call).
413    ExecutionError(String),
414
415    /// There was an IoError while reading the source code to execute.
416    ReadError(IoError),
417
418    /// The call to `execute` has requested the wrong type of data.
419    WrongType,
420}
421
422impl fmt::Display for LuaError {
423    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
424        use LuaError::*;
425
426        match *self {
427            SyntaxError(ref s) => write!(f, "Syntax error: {}", s),
428            ExecutionError(ref s) => write!(f, "Execution error: {}", s),
429            ReadError(ref e) => write!(f, "Read error: {}", e),
430            WrongType => write!(f, "Wrong type returned by Lua"),
431        }
432    }
433}
434
435impl Error for LuaError {
436    fn description(&self) -> &str {
437        use LuaError::*;
438
439        match *self {
440            SyntaxError(ref s) => &s,
441            ExecutionError(ref s) => &s,
442            ReadError(_) => "read error",
443            WrongType => "wrong type returned by Lua",
444        }
445    }
446
447    fn cause(&self) -> Option<&Error> {
448        use LuaError::*;
449
450        match *self {
451            SyntaxError(_) => None,
452            ExecutionError(_) => None,
453            ReadError(ref e) => Some(e),
454            WrongType => None,
455        }
456    }
457}
458
459impl From<io::Error> for LuaError {
460    fn from(e: io::Error) -> Self {
461        LuaError::ReadError(e)
462    }
463}
464
465impl<'lua> Lua<'lua> {
466    /// Builds a new empty Lua context.
467    ///
468    /// There are no global variables and the registry is totally empty. Even the functions from
469    /// the standard library can't be used.
470    ///
471    /// If you want to use the Lua standard library in the scripts of this context, see
472    /// [the openlibs method](#method.openlibs)
473    ///
474    /// # Example
475    ///
476    /// ```
477    /// use hlua::Lua;
478    /// let mut lua = Lua::new();
479    /// ```
480    ///
481    /// # Panic
482    ///
483    /// The function panics if the underlying call to `lua_newstate` fails
484    /// (which indicates lack of memory).
485    #[inline]
486    pub fn new() -> Lua<'lua> {
487        let lua = unsafe { ffi::lua_newstate(alloc, std::ptr::null_mut()) };
488        if lua.is_null() {
489            panic!("lua_newstate failed");
490        }
491
492        // this alloc function is required to create a lua state.
493        extern "C" fn alloc(_ud: *mut libc::c_void,
494                            ptr: *mut libc::c_void,
495                            _osize: libc::size_t,
496                            nsize: libc::size_t)
497                            -> *mut libc::c_void {
498            unsafe {
499                if nsize == 0 {
500                    libc::free(ptr as *mut libc::c_void);
501                    std::ptr::null_mut()
502                } else {
503                    libc::realloc(ptr, nsize)
504                }
505            }
506        }
507
508        // called whenever lua encounters an unexpected error.
509        extern "C" fn panic(lua: *mut ffi::lua_State) -> libc::c_int {
510            let err = unsafe { ffi::lua_tostring(lua, -1) };
511            let err = unsafe { CStr::from_ptr(err) };
512            let err = String::from_utf8(err.to_bytes().to_vec()).unwrap();
513            panic!("PANIC: unprotected error in call to Lua API ({})\n", err);
514        }
515
516        unsafe { ffi::lua_atpanic(lua, panic) };
517
518        Lua {
519            lua: LuaContext(lua),
520            must_be_closed: true,
521            marker: PhantomData,
522        }
523    }
524
525    /// Takes an existing `lua_State` and build a Lua object from it.
526    ///
527    /// If `close_at_the_end` is true, `lua_close` will be called on the `lua_State` in the
528    /// destructor.
529    #[inline]
530    pub unsafe fn from_existing_state<T>(lua: *mut T, close_at_the_end: bool) -> Lua<'lua> {
531        Lua {
532            lua: std::mem::transmute(lua),
533            must_be_closed: close_at_the_end,
534            marker: PhantomData,
535        }
536    }
537
538    /// Opens all standard Lua libraries.
539    ///
540    /// See the reference for the standard library here:
541    /// https://www.lua.org/manual/5.2/manual.html#6
542    ///
543    /// This is done by calling `luaL_openlibs`.
544    ///
545    /// # Example
546    ///
547    /// ```
548    /// use hlua::Lua;
549    /// let mut lua = Lua::new();
550    /// lua.openlibs();
551    /// ```
552    #[inline]
553    pub fn openlibs(&mut self) {
554        unsafe { ffi::luaL_openlibs(self.lua.0) }
555    }
556
557    /// Opens base library.
558    ///
559    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_base
560    #[inline]
561    pub fn open_base(&mut self) {
562        unsafe { ffi::luaopen_base(self.lua.0) }
563    }
564
565    /// Opens bit32 library.
566    ///
567    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_bit32
568    #[inline]
569    pub fn open_bit32(&mut self) {
570        unsafe { ffi::luaopen_bit32(self.lua.0) }
571    }
572
573    /// Opens coroutine library.
574    ///
575    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_coroutine
576    #[inline]
577    pub fn open_coroutine(&mut self) {
578        unsafe { ffi::luaopen_coroutine(self.lua.0) }
579    }
580
581    /// Opens debug library.
582    ///
583    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_debug
584    #[inline]
585    pub fn open_debug(&mut self) {
586        unsafe { ffi::luaopen_debug(self.lua.0) }
587    }
588
589    /// Opens io library.
590    ///
591    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_io
592    #[inline]
593    pub fn open_io(&mut self) {
594        unsafe { ffi::luaopen_io(self.lua.0) }
595    }
596
597    /// Opens math library.
598    ///
599    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_math
600    #[inline]
601    pub fn open_math(&mut self) {
602        unsafe { ffi::luaopen_math(self.lua.0) }
603    }
604
605    /// Opens os library.
606    ///
607    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_os
608    #[inline]
609    pub fn open_os(&mut self) {
610        unsafe { ffi::luaopen_os(self.lua.0) }
611    }
612
613    /// Opens package library.
614    ///
615    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_package
616    #[inline]
617    pub fn open_package(&mut self) {
618        unsafe { ffi::luaopen_package(self.lua.0) }
619    }
620
621    /// Opens string library.
622    ///
623    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_string
624    #[inline]
625    pub fn open_string(&mut self) {
626        unsafe { ffi::luaopen_string(self.lua.0) }
627    }
628
629    /// Opens table library.
630    ///
631    /// https://www.lua.org/manual/5.2/manual.html#pdf-luaopen_table
632    #[inline]
633    pub fn open_table(&mut self) {
634        unsafe { ffi::luaopen_table(self.lua.0) }
635    }
636
637    /// Executes some Lua code in the context.
638    ///
639    /// The code will have access to all the global variables you set with methods such as `set`.
640    /// Every time you execute some code in the context, the code can modify these global variables.
641    ///
642    /// The template parameter of this function is the return type of the expression that is being
643    /// evaluated.
644    /// In order to avoid compilation error, you should call this function either by doing
645    /// `lua.execute::<T>(...)` or `let result: T = lua.execute(...);` where `T` is the type of
646    /// the expression.
647    /// The function will return an error if the actual return type of the expression doesn't
648    /// match the template parameter.
649    ///
650    /// The return type must implement the `LuaRead` trait. See
651    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
652    /// information.
653    ///
654    /// # Examples
655    ///
656    /// Without a return value:
657    ///
658    /// ```
659    /// use hlua::Lua;
660    /// let mut lua = Lua::new();
661    /// lua.execute::<()>("function multiply_by_two(a) return a * 2 end").unwrap();
662    /// lua.execute::<()>("twelve = multiply_by_two(6)").unwrap();
663    /// ```
664    ///
665    /// With a return value:
666    ///
667    /// ```
668    /// use hlua::Lua;
669    /// let mut lua = Lua::new();
670    ///
671    /// let twelve: i32 = lua.execute("return 3 * 4;").unwrap();
672    /// let sixty = lua.execute::<i32>("return 6 * 10;").unwrap();
673    /// ```
674    #[inline]
675    pub fn execute<'a, T>(&'a mut self, code: &str) -> Result<T, LuaError>
676        where T: for<'g> LuaRead<PushGuard<&'g mut PushGuard<&'a mut Lua<'lua>>>>
677    {
678        let mut f = try!(lua_functions::LuaFunction::load(self, code));
679        f.call()
680    }
681
682    /// Executes some Lua code on the context.
683    ///
684    /// This does the same thing as [the `execute` method](#method.execute), but the code to
685    /// execute is loaded from an object that implements `Read`.
686    ///
687    /// Use this method when you potentially have a large amount of code (for example if you read
688    /// the code from a file) in order to avoid having to put everything in memory first before
689    /// passing it to the Lua interpreter.
690    ///
691    /// # Example
692    ///
693    /// ```no_run
694    /// use std::fs::File;
695    /// use hlua::Lua;
696    ///
697    /// let mut lua = Lua::new();
698    /// let script = File::open("script.lua").unwrap();
699    /// lua.execute_from_reader::<(), _>(script).unwrap();
700    /// ```
701    #[inline]
702    pub fn execute_from_reader<'a, T, R>(&'a mut self, code: R) -> Result<T, LuaError>
703        where T: for<'g> LuaRead<PushGuard<&'g mut PushGuard<&'a mut Lua<'lua>>>>,
704              R: Read
705    {
706        let mut f = try!(lua_functions::LuaFunction::load_from_reader(self, code));
707        f.call()
708    }
709
710    /// Reads the value of a global variable.
711    ///
712    /// Returns `None` if the variable doesn't exist or has the wrong type.
713    ///
714    /// The type must implement the `LuaRead` trait. See
715    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
716    /// information.
717    ///
718    /// # Example
719    ///
720    /// ```
721    /// use hlua::Lua;
722    /// let mut lua = Lua::new();
723    /// lua.execute::<()>("a = 5").unwrap();
724    /// let a: i32 = lua.get("a").unwrap();
725    /// assert_eq!(a, 5);
726    /// ```
727    #[inline]
728    pub fn get<'l, V, I>(&'l mut self, index: I) -> Option<V>
729        where I: Borrow<str>,
730              V: LuaRead<PushGuard<&'l mut Lua<'lua>>>
731    {
732        let index = CString::new(index.borrow()).unwrap();
733        unsafe {
734            ffi::lua_getglobal(self.lua.0, index.as_ptr());
735        }
736        if unsafe { ffi::lua_isnil(self.as_lua().0, -1) } {
737            let raw_lua = self.as_lua();
738            let _guard = PushGuard {
739                lua: self,
740                size: 1,
741                raw_lua: raw_lua,
742            };
743            return None;
744        }
745        let raw_lua = self.as_lua();
746        let guard = PushGuard {
747            lua: self,
748            size: 1,
749            raw_lua: raw_lua,
750        };
751        LuaRead::lua_read(guard).ok()
752    }
753
754    /// Reads the value of a global, capturing the context by value.
755    #[inline]
756    pub fn into_get<V, I>(self, index: I) -> Result<V, PushGuard<Self>>
757        where I: Borrow<str>,
758              V: LuaRead<PushGuard<Lua<'lua>>>
759    {
760        let index = CString::new(index.borrow()).unwrap();
761        unsafe {
762            ffi::lua_getglobal(self.lua.0, index.as_ptr());
763        }
764        let is_nil = unsafe { ffi::lua_isnil(self.as_lua().0, -1) };
765        let raw_lua = self.as_lua();
766        let guard = PushGuard {
767            lua: self,
768            size: 1,
769            raw_lua: raw_lua,
770        };
771        if is_nil {
772            Err(guard)
773        } else {
774            LuaRead::lua_read(guard)
775        }
776    }
777
778    /// Modifies the value of a global variable.
779    ///
780    /// If you want to write an array, you are encouraged to use
781    /// [the `empty_array` method](#method.empty_array) instead.
782    ///
783    /// The type must implement the `PushOne` trait. See
784    /// [the documentation at the crate root](index.html#pushing-and-loading-values) for more
785    /// information.
786    ///
787    /// # Example
788    ///
789    /// ```
790    /// use hlua::Lua;
791    /// let mut lua = Lua::new();
792    ///
793    /// lua.set("a", 12);
794    /// let six: i32 = lua.execute("return a / 2;").unwrap();
795    /// assert_eq!(six, 6);
796    /// ```
797    #[inline]
798    pub fn set<I, V, E>(&mut self, index: I, value: V)
799        where I: Borrow<str>,
800              for<'a> V: PushOne<&'a mut Lua<'lua>, Err = E>,
801              E: Into<Void>,
802    {
803        match self.checked_set(index, value) {
804            Ok(_) => (),
805            Err(_) => unreachable!(),
806        }
807    }
808
809    /// Modifies the value of a global variable.
810    // TODO: docs
811    #[inline]
812    pub fn checked_set<I, V, E>(&mut self, index: I, value: V) -> Result<(), E>
813        where I: Borrow<str>,
814              for<'a> V: PushOne<&'a mut Lua<'lua>, Err = E>
815    {
816        unsafe {
817            // TODO: can be simplified
818            let mut me = self;
819            ffi::lua_pushglobaltable(me.lua.0);
820            match index.borrow().push_to_lua(&mut me) {
821                Ok(pushed) => {
822                    debug_assert_eq!(pushed.size, 1);
823                    pushed.forget()
824                }
825                Err(_) => unreachable!(),
826            };
827            match value.push_to_lua(&mut me) {
828                Ok(pushed) => {
829                    assert_eq!(pushed.size, 1);
830                    pushed.forget()
831                }
832                Err((err, lua)) => {
833                    ffi::lua_pop(lua.lua.0, 2);
834                    return Err(err);
835                }
836            };
837            ffi::lua_settable(me.lua.0, -3);
838            ffi::lua_pop(me.lua.0, 1);
839            Ok(())
840        }
841    }
842
843    /// Sets the value of a global variable to an empty array, then loads it.
844    ///
845    /// This is the function you should use if you want to set the value of a global variable to
846    /// an array. After calling it, you will obtain a `LuaTable` object which you can then fill
847    /// with the elements of the array.
848    ///
849    /// # Example
850    ///
851    /// ```
852    /// use hlua::Lua;
853    /// let mut lua = Lua::new();
854    /// lua.openlibs();     // Necessary for `ipairs`.
855    ///
856    /// {
857    ///     let mut array = lua.empty_array("my_values");
858    ///     array.set(1, 10);       // Don't forget that Lua arrays are indexed from 1.
859    ///     array.set(2, 15);
860    ///     array.set(3, 20);
861    /// }
862    ///
863    /// let sum: i32 = lua.execute(r#"
864    ///     local sum = 0
865    ///     for i, val in ipairs(my_values) do
866    ///         sum = sum + val
867    ///     end
868    ///     return sum
869    /// "#).unwrap();
870    ///
871    /// assert_eq!(sum, 45);
872    /// ```
873    #[inline]
874    pub fn empty_array<'a, I>(&'a mut self, index: I) -> LuaTable<PushGuard<&'a mut Lua<'lua>>>
875        where I: Borrow<str>
876    {
877        unsafe {
878            let mut me = self;
879            ffi::lua_pushglobaltable(me.lua.0);
880            match index.borrow().push_to_lua(&mut me) {
881                Ok(pushed) => pushed.forget(),
882                Err(_) => unreachable!(),
883            };
884            ffi::lua_newtable(me.lua.0);
885            ffi::lua_settable(me.lua.0, -3);
886            ffi::lua_pop(me.lua.0, 1);
887
888            // TODO: cleaner implementation
889            me.get(index).unwrap()
890        }
891    }
892
893    /// Loads the array containing the global variables.
894    ///
895    /// In lua, the global variables accessible from the lua code are all part of a table which
896    /// you can load here.
897    ///
898    /// # Examples
899    ///
900    /// The function can be used to write global variables, just like `set`.
901    ///
902    /// ```
903    /// use hlua::Lua;
904    /// let mut lua = Lua::new();
905    /// lua.globals_table().set("a", 5);
906    /// assert_eq!(lua.get::<i32, _>("a"), Some(5));
907    /// ```
908    ///
909    /// A more useful feature for this function is that it allows you to set the metatable of the
910    /// global variables. See TODO for more info.
911    ///
912    /// ```
913    /// use hlua::Lua;
914    /// use hlua::AnyLuaValue;
915    ///
916    /// let mut lua = Lua::new();
917    /// {
918    ///     let mut metatable = lua.globals_table().get_or_create_metatable();
919    ///     metatable.set("__index", hlua::function2(|_: AnyLuaValue, var: String| -> AnyLuaValue {
920    ///         println!("The user tried to access the variable {:?}", var);
921    ///         AnyLuaValue::LuaNumber(48.0)
922    ///     }));
923    /// }
924    ///
925    /// let b: i32 = lua.execute("return b * 2;").unwrap();
926    /// // -> The user tried to access the variable "b"
927    ///
928    /// assert_eq!(b, 96);
929    /// ```
930    #[inline]
931    pub fn globals_table<'a>(&'a mut self) -> LuaTable<PushGuard<&'a mut Lua<'lua>>> {
932        unsafe {
933            ffi::lua_pushglobaltable(self.lua.0);
934        }
935        let raw_lua = self.as_lua();
936        let guard = PushGuard {
937            lua: self,
938            size: 1,
939            raw_lua: raw_lua,
940        };
941        LuaRead::lua_read(guard).ok().unwrap()
942    }
943}
944
945impl<'lua> Drop for Lua<'lua> {
946    #[inline]
947    fn drop(&mut self) {
948        if self.must_be_closed {
949            unsafe { ffi::lua_close(self.lua.0) }
950        }
951    }
952}
953
954impl<L> Drop for PushGuard<L> {
955    #[inline]
956    fn drop(&mut self) {
957        if self.size != 0 {
958            unsafe {
959                ffi::lua_pop(self.raw_lua.0, self.size);
960            }
961        }
962    }
963}
964
965#[cfg(test)]
966mod tests {
967    use Lua;
968    use LuaError;
969
970    #[test]
971    fn open_base_opens_base_library() {
972        let mut lua = Lua::new();
973        match lua.execute::<()>("return assert(true)") {
974            Err(LuaError::ExecutionError(_)) => { },
975            Err(_) => panic!("Wrong error"),
976            Ok(_) => panic!("Unexpected success"),
977        }
978        lua.open_base();
979        let result: bool = lua.execute("return assert(true)").unwrap();
980        assert_eq!(result, true);
981    }
982
983    #[test]
984    fn opening_all_libraries_doesnt_panic() {
985        let mut lua = Lua::new();
986        lua.open_base();
987        lua.open_bit32();
988        lua.open_coroutine();
989        lua.open_debug();
990        lua.open_io();
991        lua.open_math();
992        lua.open_os();
993        lua.open_package();
994        lua.open_string();
995        lua.open_table();
996    }
997}