Skip to content

Commit

Permalink
Merge pull request #14 from esimkowitz/evan/js-sys
Browse files Browse the repository at this point in the history
Add native support for WASM targets
  • Loading branch information
Yuri6037 authored Jul 22, 2023
2 parents 53328f3 + 9bad169 commit 3bff1e3
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 19 deletions.
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ cfg-if = "1.0.0"
thiserror = { version = "1.0.30", optional = true }
nom = { version = "7.1.0", optional = true }

[target.'cfg(not(target_family = "wasm"))'.dependencies]
time = { version = "0.3.7", features = ["macros"] }

[target.'cfg(target_family = "wasm")'.dependencies]
js-sys = { version = "0.3.64", optional = true }
time = { version = "0.3.7", features = ["macros", "wasm-bindgen"] }
wasm-bindgen = "0.2.87"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.32.0", features = ["Win32_System_Time", "Win32_Foundation"], optional = true }

Expand All @@ -31,7 +39,7 @@ serde = { version = "1.0.136", features = ["derive"] }

[features]
default = ["db"]
system = ["windows-sys", "thiserror", "db"]
system = ["windows-sys", "js-sys", "thiserror", "db"]
posix-tz = ["nom", "thiserror", "db"]
db = []

Expand Down
36 changes: 20 additions & 16 deletions src/binary_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,23 @@ pub fn binary_search<F: Fn(usize) -> Ordering>(start: usize, end: usize, cmp: F)
}
}

#[test]
fn test_binary_search() {
assert_eq!(binary_search(0, 8, |x| x.cmp(&6)), Some(6));
assert_eq!(binary_search(0, 5000, |x| x.cmp(&1337)), Some(1337));
assert_eq!(binary_search(0, 5000, |x| x.cmp(&9000)), None);
assert_eq!(binary_search(30, 50, |x| x.cmp(&42)), Some(42));
assert_eq!(binary_search(300, 500, |x| x.cmp(&42)), None);
assert_eq!(
binary_search(0, 500, |x| if x < 42 {
Ordering::Less
} else {
Ordering::Greater
}),
None
);
}
#[cfg(test)]
mod tests {
#[test]
fn test_binary_search() {
assert_eq!(super::binary_search(0, 8, |x| x.cmp(&6)), Some(6));
assert_eq!(super::binary_search(0, 5000, |x| x.cmp(&1337)), Some(1337));
assert_eq!(super::binary_search(0, 5000, |x| x.cmp(&9000)), None);
assert_eq!(super::binary_search(30, 50, |x| x.cmp(&42)), Some(42));
assert_eq!(super::binary_search(300, 500, |x| x.cmp(&42)), None);
assert_eq!(
super::binary_search(0, 500, |x| if x < 42 {
super::Ordering::Less
} else {
super::Ordering::Greater
}),
None
);
}

}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub trait PrimitiveDateTimeExt: sealing::PrimitiveDateTimeExt {
///
/// * `tz`: the target timezone.
///
/// returns: OffsetResult<OffsetDateTime>
/// returns: `OffsetResult<OffsetDateTime>`
fn assume_timezone<T: TimeZone>(&self, tz: &T) -> OffsetResult<OffsetDateTime>;

/// Creates a new OffsetDateTime with the proper offset in the given timezone.
Expand Down
34 changes: 33 additions & 1 deletion src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//! Support for getting time zone information from the target system.
//!
//! Currently only supported for Windows, Unix, and WASM targets.

use crate::timezones::get_by_name;
use crate::Tz;
use thiserror::Error;

#[cfg(target_family = "wasm")]
use js_sys::{ Intl, Reflect, Array, Object };
#[cfg(target_family = "wasm")]
use wasm_bindgen::JsValue;

#[derive(Debug, Error)]
pub enum Error {
/// An IO error has occurred.
Expand All @@ -52,8 +61,18 @@ pub enum Error {
/// The timezone doesn't exist in the crate's database.
#[error("unknown timezone name")]
Unknown,

/// The target platform is not supported. Windows, Unix, and WASM targets are the only supported for the system feature at this moment.
#[error("unsupported platform")]
Unsupported,
}

/// Gets the current timezone from the system.
///
/// Currently only supported for Windows, Unix, and WASM targets.
///
/// # Errors
/// Returns an [Error](enum@Error) if the timezone cannot be determined.
pub fn get_timezone() -> Result<&'static Tz, Error> {
cfg_if::cfg_if! {
if #[cfg(unix)] {
Expand All @@ -67,7 +86,7 @@ pub fn get_timezone() -> Result<&'static Tz, Error> {
} else {
Err(Error::Undetermined)
}
} else {
} else if #[cfg(windows)] {
unsafe {
use windows_sys::Win32::System::Time::GetDynamicTimeZoneInformation;
use windows_sys::Win32::System::Time::DYNAMIC_TIME_ZONE_INFORMATION;
Expand All @@ -89,6 +108,19 @@ pub fn get_timezone() -> Result<&'static Tz, Error> {
Ok(tz)
}
}
} else if #[cfg(target_family = "wasm")] {
let options = Intl::DateTimeFormat::new(&Array::new(), &Object::new())
.resolved_options();

let tz = Reflect::get(&options, &JsValue::from("timeZone"))
.map_err(|_| Error::Undetermined)?
.as_string()
.ok_or(Error::Unicode)?;

let tz = get_by_name(&tz).ok_or(Error::Unknown)?;
Ok(tz)
} else {
Err(Error::Unsupported)
}
}
}
Expand Down

0 comments on commit 3bff1e3

Please sign in to comment.