Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat(std): add time module to standard library #779

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
474387f
feat(std): add std::time bindings
Etherian Aug 24, 2019
5c51709
feat(std): add std.time module
Etherian Aug 24, 2019
a878f7b
feat(std): restructure std.time
Etherian Aug 30, 2019
db6add0
Merge branch 'master' into time
Etherian Sep 1, 2019
04b4bf7
add rest of std::time functions
Etherian Sep 11, 2019
b47e513
Merge branch 'master' into time
Etherian Sep 12, 2019
905a314
wrap return of Instant.now & SystemTime.now in IO monad, since they b…
Etherian Sep 25, 2019
1c3e5b4
add eq and lt functions to each type
Etherian Sep 29, 2019
f50c72f
reformat std.time and add docs for std.time.duration
Etherian Sep 29, 2019
593a376
fix imports in std.time modules
Etherian Oct 1, 2019
30e5cfb
various cleanups and fixes
Etherian Oct 14, 2019
9eb327c
Merge branch 'master' into time
Etherian Oct 14, 2019
8ff4a16
Merge branch 'master' into time
Etherian Oct 21, 2019
f38694d
fix(std): remove panic condition of time.instant.elapsed
Etherian Oct 26, 2019
13066ca
add docs for std.time.instant
Etherian Jul 2, 2020
08ddac7
Merge branch 'master' into time
Etherian Jul 3, 2020
b8b70c5
Merge branch 'master' into time
Etherian Aug 14, 2020
49eab26
Merge branch 'master' into time
Etherian Aug 16, 2020
608fb89
Merge branch 'master' into time
Etherian Aug 18, 2020
4d6b6f5
feat(std): add saturating_duration_since to instant and system_time
Etherian Sep 6, 2020
1bd60a7
doc(std): add docs to system_time.glu
Etherian Sep 6, 2020
2eaaf1d
add saturating_duration_since to instant.glu
Etherian Sep 6, 2020
3e98782
clean up doc comments in duration.glu and instant.glu
Etherian Sep 6, 2020
0fe007e
Merge branch 'master' into time
Etherian Sep 7, 2020
996e0cc
feat(std.time): expose types in std.time
Etherian Jul 30, 2021
6f931e0
Merge branch 'master' into time
Etherian Jul 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,7 @@ impl VmBuilder {
add_extern_module(&vm, "std.io.prim", crate::std_lib::io::load);
add_extern_module(&vm, "std.process.prim", crate::std_lib::process::load);
add_extern_module(&vm, "std.env.prim", crate::std_lib::env::load);
add_extern_module(&vm, "std.time.prim", crate::std_lib::time::load);

add_extern_module_if!(
#[cfg(feature = "serialization")],
Expand Down
1 change: 1 addition & 0 deletions src/std_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod process;
pub mod random;
#[cfg(feature = "regex")]
pub mod regex;
pub mod time;
111 changes: 111 additions & 0 deletions src/std_lib/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//! Module containing bindings to rust's `std::time` module.
//!
use crate::real_std::{
time,
convert::TryInto,
};

use crate::vm::{
self,
api::{Eff, IO},
thread::Thread,
types::VmInt,
ExternModule,
};

#[derive(Clone, Debug, Userdata, Trace, VmType)]
#[gluon(vm_type = "std.time.types.Duration")]
#[gluon(crate_name = "::vm")]
#[gluon_trace(skip)]
Etherian marked this conversation as resolved.
Show resolved Hide resolved
struct Duration(time::Duration);

fn as_secs(dur: &Duration) -> VmInt {
dur.0.as_secs().try_into().expect("Overflow when trying to convert Duration into seconds")
Etherian marked this conversation as resolved.
Show resolved Hide resolved
}

fn subsec_nanos(dur: &Duration) -> VmInt {
dur.0.subsec_nanos() as VmInt
}

#[derive(Clone, Debug, Userdata, Trace, VmType)]
#[gluon(vm_type = "std.time.types.Instant")]
#[gluon(crate_name = "::vm")]
#[gluon_trace(skip)]
struct Instant(time::Instant);

fn instant_now(_: ()) -> IO<Instant> {
IO::Value(Instant(time::Instant::now()))
}

/// Returns `Some(later - earlier)` if `later` is the same as or later than `earlier`.
/// Returns None otherwise.
fn instant_since(later: &Instant, earlier: &Instant) -> Option<Duration> {
// Note: replace with checked_duration_since when 1.38 is stable
if later.0 >= earlier.0 {
// should never panic
Some(Duration(later.0.duration_since(earlier.0)))
} else {
None
}
}

fn instant_elapsed(earlier: &Instant) -> Duration {
Duration(earlier.0.elapsed())
}

#[derive(Clone, Debug, Userdata, Trace, VmType)]
#[gluon(vm_type = "std.time.types.SystemTime")]
#[gluon(crate_name = "::vm")]
#[gluon_trace(skip)]
struct SystemTime(time::SystemTime);

fn system_time_now(_: ()) -> IO<SystemTime> {
IO::Value(SystemTime(time::SystemTime::now()))
}

/// Returns `Ok(later - earlier)` if `later` is the same as or later than `earlier`.
/// Returns `Err(earlier - later)` if `later` is earlier than `earlier`.
fn system_time_since(later : &SystemTime, earlier : &SystemTime) -> Result<Duration, Duration> {
later.0.duration_since(earlier.0)
.map(|x| Duration(x))
.map_err(|e| Duration(e.duration()))
}

fn system_time_elapsed(earlier: &SystemTime) -> Result<Duration, Duration> {
earlier.0.elapsed()
.map(|x| Duration(x))
.map_err(|e| Duration(e.duration()))
}

mod std {
pub mod time {
pub use crate::std_lib::time as prim;
}
}

pub fn load(vm: &Thread) -> vm::Result<ExternModule> {
vm.register_type::<Duration>("std.time.types.Duration", &[])?;
vm.register_type::<Instant>("std.time.types.Instant", &[])?;
vm.register_type::<SystemTime>("std.time.types.SystemTime", &[])?;

ExternModule::new(
vm,
record! {
type std::time::Duration => Duration,
type std::time::Instant => Instant,
type std::time::SystemTime => SystemTime,

unix_epoch => SystemTime(time::UNIX_EPOCH),

as_secs => primitive!(1, std::time::prim::as_secs),
subsec_nanos => primitive!(1, std::time::prim::subsec_nanos),
instant_now => primitive!(1, std::time::prim::instant_now),
instant_since => primitive!(2, std::time::prim::instant_since),
instant_elapsed => primitive!(1, std::time::prim::instant_elapsed),
system_time_now => primitive!(1, std::time::prim::system_time_now),
system_time_since => primitive!(2, std::time::prim::system_time_since),
system_time_elapsed => primitive!(1, std::time::prim::system_time_elapsed),

},
)
}
8 changes: 8 additions & 0 deletions std/time.glu
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Time-related functionality

let time = import! std.time.prim

{
..
time
}