use crate::{
builtins::{BuiltInBuilder, BuiltInObject, IntrinsicObject},
context::intrinsics::Intrinsics,
js_string,
property::Attribute,
realm::Realm,
string::StaticJsStrings,
sys::time::SystemTime,
Context, JsBigInt, JsNativeError, JsObject, JsResult, JsString, JsSymbol, JsValue,
};
use boa_profiler::Profiler;
use temporal_rs::components::tz::TimeZone;
use super::{ns_max_instant, ns_min_instant, time_zone::default_time_zone};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Now;
impl IntrinsicObject for Now {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(std::any::type_name::<Self>(), "init");
BuiltInBuilder::with_intrinsic::<Self>(realm)
.static_property(
JsSymbol::to_string_tag(),
Self::NAME,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.static_method(Self::time_zone_id, js_string!("timeZoneId"), 0)
.static_method(Self::instant, js_string!("instant"), 0)
.static_method(Self::plain_date_time, js_string!("plainDateTime"), 2)
.static_method(Self::plain_date_time_iso, js_string!("plainDateTimeISO"), 1)
.static_method(Self::zoned_date_time, js_string!("zonedDateTime"), 2)
.static_method(Self::zoned_date_time_iso, js_string!("zonedDateTimeISO"), 1)
.static_method(Self::plain_date, js_string!("plainDate"), 2)
.static_method(Self::plain_date_iso, js_string!("plainDateISO"), 1)
.build();
}
fn get(intrinsics: &Intrinsics) -> JsObject {
intrinsics.objects().now()
}
}
impl BuiltInObject for Now {
const NAME: JsString = StaticJsStrings::NOW;
}
impl Now {
#[allow(clippy::unnecessary_wraps)]
fn time_zone_id(_: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
system_time_zone(context)?
.id()
.map(|s| JsValue::from(js_string!(s.as_str())))
.map_err(Into::into)
}
fn instant(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn plain_date_time(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn plain_date_time_iso(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn zoned_date_time(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn zoned_date_time_iso(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn plain_date(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
fn plain_date_iso(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult<JsValue> {
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}
}
fn host_system_utc_epoch_nanoseconds() -> JsResult<JsBigInt> {
let epoch_nanos = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.map_err(|e| JsNativeError::range().with_message(e.to_string()))?
.as_nanos();
Ok(clamp_epoc_nanos(JsBigInt::from(epoch_nanos)))
}
fn clamp_epoc_nanos(ns: JsBigInt) -> JsBigInt {
let max = ns_max_instant();
let min = ns_min_instant();
ns.clamp(min, max)
}
#[allow(unused)]
fn system_utc_epoch_millis() -> JsResult<f64> {
let now = host_system_utc_epoch_nanoseconds()?;
Ok(now.to_f64().div_euclid(1_000_000_f64).floor())
}
#[allow(unused)]
fn system_utc_epoch_nanos() -> JsResult<JsBigInt> {
host_system_utc_epoch_nanoseconds()
}
#[allow(unused)]
fn system_instant() {
todo!()
}
#[allow(unused)]
fn system_date_time() {
todo!()
}
#[allow(unused)]
fn system_zoned_date_time() {
todo!()
}
#[allow(unused)]
fn system_time_zone(context: &mut Context) -> JsResult<TimeZone> {
let identifier = default_time_zone(context);
Err(JsNativeError::error()
.with_message("not yet implemented.")
.into())
}