boa
boa copied to clipboard
Safe wrapper for `JsDate`
This PR adds a safe wrapper around JavaScript JsDate
from builtins::date
, and is being tracked at #2098.
Implements following methods
- [x]
new Date()
- [x]
Date.prototype.getDate()
- [x]
Date.prototype.getDay()
- [x]
Date.prototype.getFullYear()
- [x]
Date.prototype.getHours()
- [x]
Date.prototype.getMilliseconds()
- [x]
Date.prototype.getMinutes()
- [x]
Date.prototype.getMonth()
- [x]
Date.prototype.getSeconds()
- [x]
Date.prototype.getTime()
- [x]
Date.prototype.getTimezoneOffset()
- [x]
Date.prototype.getUTCDate()
- [x]
Date.prototype.getUTCDay()
- [x]
Date.prototype.getUTCFullYear()
- [x]
Date.prototype.getUTCHours()
- [x]
Date.prototype.getUTCMilliseconds()
- [x]
Date.prototype.getUTCMinutes()
- [x]
Date.prototype.getUTCMonth()
- [x]
Date.prototype.getUTCSeconds()
- [x]
Date.prototype.getYear()
- [x]
Date.now()
- [ ]
Date.parse()
Issue 4 - [x]
Date.prototype.setDate()
- [x]
Date.prototype.setFullYear()
- [ ]
Date.prototype.setHours()
Issue 3 - [x]
Date.prototype.setMilliseconds()
- [ ]
Date.prototype.setMinutes()
Issue 3 - [x]
Date.prototype.setMonth()
- [x]
Date.prototype.setSeconds()
- [x]
Date.prototype.setTime()
- [x]
Date.prototype.setUTCDate()
- [x]
Date.prototype.setUTCFullYear()
- [x]
Date.prototype.setUTCHours()
- [x]
Date.prototype.setUTCMilliseconds()
- [x]
Date.prototype.setUTCMinutes()
- [x]
Date.prototype.setUTCMonth()
- [x]
Date.prototype.setUTCSeconds()
- [x]
Date.prototype.setYear()
- [ ]
Date.prototype.toDateString()
Issue 5 - [ ]
Date.prototype.toGMTString()
Issue 5 - [ ]
Date.prototype.toISOString()
Issue 5 - [ ]
Date.prototype.toJSON()
Issue 5 - [ ]
Date.prototype.toLocaleDateString()
Issue 5 and 6 - [ ]
Date.prototype.toLocaleString()
Issue 5 and 6 - [ ]
Date.prototype.toLocaleTimeString()
Issue 5 and 6 - [ ]
Date.prototype.toString()
Issue 5 - [ ]
Date.prototype.toTimeString()
Issue 5 - [ ]
Date.prototype.toUTCString()
Issue 5 - [x]
Date.UTC()
- [x]
Date.prototype.valueOf()
Issues
- ~~
get_*()
and some other methods - They take&self
as input internally, and internal struct shouldn't be used in a wrapper API. Therefore, these would require input to bethis: &JsValue, args: &[JsValue], context: &mut Context
like others and usethis_time_value()
?~~ Fixed usingthis_time_value()
- ~~
to_string()
- how can I useDate::to_string()
rather thanalloc::string::ToString
.~~ My bad it compiles, justrust-analyzer
was showing it as an issue. -
set_hours()
andset_minutes()
- they subtract local timezones when setting the value, e.g.- On further look:
// both function call `builtins::date::mod.rs#L1038 this.set_data(ObjectData::date(t)); // `ObjectData::date` creates a new `Date` object `object::mods.rs#L423 // | this date is chrono::Date<Tz(TimezoneOffset)> and Tz default is being used here which is GMT+0 pub fn date(date: Date) -> Self { Self { kind: ObjectKind::Date(date), internal_methods: &ORDINARY_INTERNAL_METHODS, } }
- BTW, in
object::mod.rs
'senum ObjectKind
there isDate(chrono::Date)
and it requires the generic argument, how is it being bypassed here? - Also in
set_minutes()
step 6,LocalTime
should be used.
// reference date = 2000-01-01T06:26:53.984
date.set_hours(&[23.into(), 23.into(), 23.into(), 23.into()], context)?;
// would add tiemzone(+5:30) to it
// Is 2000-01-01T17:53:23.023
// Should be 2000-01-01T23:23:23.023
-
parse()
- it useschrono::parse_from_rfc3339
internally, while es6 spec recommends ISO8601. And it can also parse other formats like from MDN04 Dec 1995 00:12:00 GMT
which fails. So what should be done about it. -
to_*()
- This is more general, as the internal date object useschrono::NaiveDateTime
which doesn't have timezone. It doesn't account for+4:00
in example below.
// Creates new `Date` object from given rfc3339 string.
let date = JsDate::new_from_parse(&JsValue::new("2018-01-26T18:30:09.453+04:00"), context);
println!("to_string: {:?}", date2.to_string(context)?);
// IS: Sat Jan 27 2018 00:00:09 GMT+0530
// Should: Fri Jan 26 2018 20:00:09 GMT+0530
-
to_locale_*()
- requiresToDateTimeOptions
and localization would require chrono'sunstable-locales
feature, which is available forDateTime
and not forNaiveDateTime
.- I should have looked properly,
to_date_time_options
is already implemented inbuiltins::intl
. Anyway, I would still need some tips on how to use it. What would function signature be like in wrapper API, how wouldoptions
be passed to the said API. - So
to_date_time_options()
takesoptions: &JsValue
as an argument and build an object from it and fetch properties throughObject.get()
. If I wantoptions
to be{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
what wouldJsValue
look like to make it all work.
date.to_locale_date_string(&[JsValue::new("en_EN"), OPTIONS], context)?; // OPTIONS need to be a JsValue which when converted into an object // have these properties { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
- I should have looked properly,
Possible improvements
- Right now,
object::jsdate::set_full_year()
and alike (input is a slice) are like below,into()
doesn't feel ergonomic.#[inline] pub fn set_full_year(&self, values: &[JsValue], context: &mut Context) -> JsResult<JsValue> { Date::set_full_year(&self.inner.clone().into(), values, context) } // Usage date.set_full_year(&[2000.into(), 0.into(), 1.into()], context)?; // How can something like this be made to work #[inline] pub fn set_full_year<T>(&self, values: &[T], context: &mut Context) -> JsResult<JsValue> where T: Into<JsValue>, { | expected reference `&[value::JsValue]` | found reference `&[T]` Date::set_full_year(&self.inner.clone().into(), values, context) }
- Any other suggestion?
Codecov Report
Merging #2181 (0a0c7d5) into main (2ffae5b) will increase coverage by
0.11%
. The diff coverage is49.11%
.
@@ Coverage Diff @@
## main #2181 +/- ##
==========================================
+ Coverage 38.69% 38.80% +0.11%
==========================================
Files 314 315 +1
Lines 23887 24085 +198
==========================================
+ Hits 9242 9347 +105
- Misses 14645 14738 +93
Impacted Files | Coverage Δ | |
---|---|---|
boa_engine/src/object/builtins/jsdate.rs | 0.00% <0.00%> (ø) |
|
boa_engine/src/builtins/date/mod.rs | 86.27% <87.40%> (+3.14%) |
:arrow_up: |
boa_engine/src/value/serde_json.rs | 84.44% <0.00%> (-3.93%) |
:arrow_down: |
boa_ast/src/property.rs | 18.96% <0.00%> (-1.73%) |
:arrow_down: |
boa_engine/src/vm/mod.rs | 42.74% <0.00%> (-0.35%) |
:arrow_down: |
boa_engine/src/context/mod.rs | 32.25% <0.00%> (-0.21%) |
:arrow_down: |
boa_engine/src/builtins/error/uri.rs | 100.00% <0.00%> (ø) |
|
boa_engine/src/builtins/error/eval.rs | 100.00% <0.00%> (ø) |
|
boa_engine/src/builtins/error/range.rs | 100.00% <0.00%> (ø) |
|
... and 10 more |
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
:clock1: Waiting for PR status (GitHub check) to be set, probably by CI. Bors will automatically try to run when all required PR statuses are set.
bors seems to have some problems with the github check status so I rebased the branch to hopefully fix that.
bors r+
Pull request successfully merged into main.
Build succeeded: