mod calendar;
mod source;
mod timestamp;
pub use self::source::SystemTimeSource;
use crate::gleam_stdlib::{
GleamStdlibHostProfile, GleamStdlibProfile, GleamStdlibRunState, GleamStdlibStores, IoOutput,
};
use crate::{HostProfile, HostProvider, HostProviderModule, HostRegistrationError};
use std::marker::PhantomData;
use std::time::SystemTime;
pub trait TimeSource: 'static {
fn system_time(&mut self) -> Result<SystemTime, crate::HostFailure>;
fn local_offset_seconds(&mut self) -> Result<i32, crate::HostFailure>;
}
pub trait GleamTimeHostProfile: GleamStdlibHostProfile {
type Source: TimeSource;
fn gleam_time_source(state: &mut Self::RunState) -> &mut Self::Source;
}
pub struct GleamTimeRunState<Source = SystemTimeSource> {
stdlib: GleamStdlibRunState,
source: Source,
}
#[derive(Debug, Clone, Copy)]
pub struct GleamTimeProfile<Source = SystemTimeSource>(PhantomData<fn() -> Source>);
impl<Source> GleamTimeRunState<Source> {
pub fn new(stdlib: GleamStdlibRunState, source: Source) -> Self {
Self { stdlib, source }
}
pub fn stdlib(&self) -> &GleamStdlibRunState {
&self.stdlib
}
pub fn stdlib_mut(&mut self) -> &mut GleamStdlibRunState {
&mut self.stdlib
}
pub fn source(&self) -> &Source {
&self.source
}
pub fn source_mut(&mut self) -> &mut Source {
&mut self.source
}
}
impl<Source> HostProfile for GleamTimeProfile<Source>
where
Source: TimeSource,
{
type RunState = GleamTimeRunState<Source>;
type ExternalStores = GleamStdlibStores;
}
impl<Source> GleamStdlibHostProfile for GleamTimeProfile<Source>
where
Source: TimeSource,
{
type Io = Vec<IoOutput>;
fn gleam_stdlib_stores(stores: &Self::ExternalStores) -> &GleamStdlibStores {
stores
}
fn gleam_stdlib_run_state(state: &mut Self::RunState) -> &mut GleamStdlibRunState {
&mut state.stdlib
}
fn gleam_stdlib_io(state: &mut Self::RunState) -> &mut Self::Io {
GleamStdlibProfile::gleam_stdlib_io(&mut state.stdlib)
}
}
impl<Source> GleamTimeHostProfile for GleamTimeProfile<Source>
where
Source: TimeSource,
{
type Source = Source;
fn gleam_time_source(state: &mut Self::RunState) -> &mut Self::Source {
&mut state.source
}
}
pub fn host_providers<Profile>() -> Result<Vec<HostProviderModule<Profile>>, HostRegistrationError>
where
Profile: GleamTimeHostProfile,
{
[
calendar::host_provider::<Profile>,
timestamp::host_provider::<Profile>,
]
.into_iter()
.map(|register| register())
.collect()
}
pub(super) struct TimeProvider<Profile>(PhantomData<Profile>);
impl<Profile> HostProvider<Profile> for TimeProvider<Profile>
where
Profile: GleamTimeHostProfile,
{
type State = Profile::Source;
fn project(state: &mut Profile::RunState) -> &mut Self::State {
Profile::gleam_time_source(state)
}
}
#[cfg(test)]
mod tests;