1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
use rlua::prelude::*; use rlua::{UserDataMethods, UserData, MetaMethod, Lua}; use chrono::prelude::*; #[derive(Clone)] struct LuaTime (DateTime<Utc>); impl UserData for LuaTime { fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_meta_method(MetaMethod::ToString, |_, this, _: ()| { Ok(this.0.to_rfc2822()) }); methods.add_meta_method(MetaMethod::Eq, |_, this, that: LuaTime| { Ok(this.0 == that.0) }); methods.add_meta_method(MetaMethod::Lt, |_, this, that: LuaTime| { Ok(this.0 < that.0) }); methods.add_meta_method(MetaMethod::Le, |_, this, that: LuaTime| { Ok(this.0 <= that.0) }); } } pub fn init(lua: &Lua) -> crate::Result<()> { let module = lua.create_table()?; module.set("now", lua.create_function( |_, _: ()| { Ok(LuaTime(Utc::now())) })? )?; module.set("new", lua.create_function( |_, s: String| { DateTime::parse_from_rfc2822(&s).map( |t| LuaTime(t.with_timezone(&Utc)) ).map_err( |_| LuaError::RuntimeError("Invalid time string".to_string()) ) })? )?; lua.globals().set("time", module)?; Ok(()) } #[cfg(test)] mod tests { use super::*; #[test] fn lua_time () { let lua = Lua::new(); init(&lua).unwrap(); lua.exec::<_, ()>(r#" print(time.now()) print(time.new("Fri, 28 Nov 2014 12:00:09 +0000")) "#, None).unwrap(); assert!(lua.exec::<_, ()>("print(time.new('lol'))", None).is_err()); } }