feat: replace enums with floats for timestamps in millis

This commit is contained in:
Erica Marigold 2023-08-26 15:44:07 +05:30
parent eee7a671a1
commit 83eeb77a6a
No known key found for this signature in database
GPG key ID: 23CD97ABBBCC5ED2

View file

@ -16,11 +16,26 @@ use once_cell::sync::Lazy;
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> { pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)? TableBuilder::new(lua)?
.with_function("now", |_, ()| Ok(DateTime::now()))? .with_function("now", |_, ()| Ok(DateTime::now()))?
.with_function("fromUnixTimestamp", |lua, (timestamp_type, timestamp)| { .with_function("fromUnixTimestamp", |lua, timestamp: LuaValue| {
Ok(DateTime::from_unix_timestamp( let timestamp_cloned = timestamp.clone();
TimestampType::from_lua(timestamp_type, lua)?, let timestamp_kind = TimestampType::from_lua(timestamp, lua)?;
timestamp, let timestamp = match timestamp_kind {
)) TimestampType::Seconds => timestamp_cloned.as_i64().unwrap(),
TimestampType::Millis => {
// FIXME: Remove the unwrap
// If something breaks, blame this.
// FIX: Decimal values cause panic, "no such local time".
let timestamp = timestamp_cloned.as_f64().unwrap();
(((timestamp - timestamp.fract()) * 1000_f64) // converting the whole seconds part to millis
+ timestamp.fract() * ((10_u64.pow(timestamp.fract().to_string().split('.').collect::<Vec<&str>>()[1].len() as u32)) as f64)) as i64
// adding the millis to the fract as a whole number
// HACK: 10 * (timestamp.fract().to_string().len() - 2) gives us the number of digits
// after the decimal
}
};
Ok(DateTime::from_unix_timestamp(timestamp_kind, timestamp))
})? })?
.with_function("fromIsoDate", |_, iso_date: LuaString| { .with_function("fromIsoDate", |_, iso_date: LuaString| {
Ok(DateTime::from_iso_date(iso_date.to_string_lossy())) Ok(DateTime::from_iso_date(iso_date.to_string_lossy()))
@ -44,27 +59,18 @@ pub enum TimestampType {
Seconds, Seconds,
Millis, Millis,
} }
// get fraction from f32
impl<'lua> FromLua<'lua> for TimestampType { impl<'lua> FromLua<'lua> for TimestampType {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
fn num_to_enum(num: i32) -> LuaResult<TimestampType> {
match num {
1 => Ok(TimestampType::Seconds),
2 => Ok(TimestampType::Millis),
_ => Err(LuaError::external("Invalid enum member!")),
}
}
match value { match value {
LuaValue::Integer(num) => num_to_enum(num), LuaValue::Integer(_) => Ok(TimestampType::Seconds),
LuaValue::Number(num) => num_to_enum(num as i32), LuaValue::Number(num) => Ok(if num.fract() == 0.0 {
LuaValue::String(str) => match str.to_str()?.to_lowercase().as_str() { TimestampType::Seconds
"seconds" | "sec" | "secs" => Ok(TimestampType::Seconds), } else {
"millis" | "milliseconds" | "milli" => Ok(TimestampType::Millis), TimestampType::Millis
&_ => Err(LuaError::external("Invalid enum member!")), }),
},
_ => Err(LuaError::external( _ => Err(LuaError::external(
"Invalid enum type, number or string expected", "Invalid enum type, number or integer expected",
)), )),
} }
} }