From f2cd06fcbec1d756352d296f8e595361c2cc26b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BB=D0=B0=D0=B2=D0=B0=20=D0=A3=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=97=D0=BD=D1=96!=20=D0=93=D0=B5=D1=80=D0=BE=D1=8F=D0=BC=20?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=D0=B0!?= <777696+ncave@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:09:11 +0000 Subject: [PATCH] [Rust] Added Async.Sleep and test (#3907) --- src/Fable.Cli/CHANGELOG.md | 1 + src/fable-library-rust/Cargo.toml | 13 +++++++------ src/fable-library-rust/src/Async.rs | 9 +++++++++ tests/Js/Main/AsyncTests.fs | 2 +- tests/Rust/tests/src/AsyncTests.fs | 22 +++++++++++++++++++--- tests/Rust/tests/src/TypeTests.fs | 22 +++++++++++----------- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 5722986c2b..e496445b1d 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [Rust] Added support for Dictionary/HashSet comparers (by @ncave) * [Rust] Updated support for interface object expressions (by @ncave) * [Rust] Added missing ResizeArray methods and tests (by @ncave) +* [Rust] Added Async.Sleep and test (by @ncave) ### Fixed diff --git a/src/fable-library-rust/Cargo.toml b/src/fable-library-rust/Cargo.toml index a1783daa53..0d56cbbfda 100644 --- a/src/fable-library-rust/Cargo.toml +++ b/src/fable-library-rust/Cargo.toml @@ -15,20 +15,21 @@ lrc_ptr = [] no_std = ["dep:hashbrown"] regexp = ["dep:regex"] static_do_bindings = ["dep:startup"] -threaded = ["atomic", "dep:futures"] +threaded = ["atomic", "dep:futures", "dep:futures-timer"] default = ["bigint", "datetime", "decimal", "enum_func", "enum_string", "guid", "regexp"] [dependencies] -startup = { version = "0.1", path = "vendored/startup", optional = true } +chrono = { version = "0.4", optional = true } +futures = { version = "0.3", features = ["executor", "thread-pool"], default-features = false, optional = true } +futures-timer = { version = "3.0", optional = true } hashbrown = { version = "0.14", optional = true } num-bigint = { version = "0.4", optional = true } num-integer = { version = "0.1", optional = true } num-traits = { version = "0.2", optional = true } -rust_decimal = { version = "1.35", features = ["maths"], default-features = false, optional = true } -futures = { version = "0.3", features = ["executor", "thread-pool"], optional = true } -uuid = { version = "1.10", features = ["v4"], default-features = false, optional = true } -chrono = { version = "0.4", optional = true } regex = { version = "1.10", optional = true } +rust_decimal = { version = "1.36", features = ["maths"], default-features = false, optional = true } +startup = { version = "0.1", path = "vendored/startup", optional = true } +uuid = { version = "1.10", features = ["v4"], default-features = false, optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", features = ["js"] } diff --git a/src/fable-library-rust/src/Async.rs b/src/fable-library-rust/src/Async.rs index 2babf77482..627a0f77f8 100644 --- a/src/fable-library-rust/src/Async.rs +++ b/src/fable-library-rust/src/Async.rs @@ -9,6 +9,7 @@ pub mod Async_ { use futures::executor::{self, LocalPool}; use futures::lock::Mutex; use futures::FutureExt; + use futures_timer::Delay; use super::Task_::Task; @@ -38,6 +39,14 @@ pub mod Async_ { } } + pub fn sleep(milliseconds: i32) -> Arc> { + let fut = Delay::new(Duration::from_millis(milliseconds as u64)); + let a: Pin + Send + Sync + 'static>> = Box::pin(fut); + Arc::from(Async { + future: Arc::from(Mutex::from(a)), + }) + } + pub fn startAsTask(a: Arc>) -> Arc> { let unitFut = async move { let mut res = a.future.lock().await; diff --git a/tests/Js/Main/AsyncTests.fs b/tests/Js/Main/AsyncTests.fs index c328f62ff5..4e4044896e 100644 --- a/tests/Js/Main/AsyncTests.fs +++ b/tests/Js/Main/AsyncTests.fs @@ -547,7 +547,7 @@ let tests = equal x "ABCDEF" } - testCaseAsync "Async.StartChild applys timeout" <| fun () -> + testCaseAsync "Async.StartChild applies timeout" <| fun () -> async { let mutable x = "" diff --git a/tests/Rust/tests/src/AsyncTests.fs b/tests/Rust/tests/src/AsyncTests.fs index cc8dfdb818..a7c17c8ded 100644 --- a/tests/Rust/tests/src/AsyncTests.fs +++ b/tests/Rust/tests/src/AsyncTests.fs @@ -102,7 +102,6 @@ let shouldExecuteTask () = // t.Join() // x |> equal 2 - // [] // let monitorShouldWorkWithSystemObj () = // let o = new System.Object() // todo - this doesn't work, and outputs unit @@ -175,6 +174,24 @@ let ``Lock should return result`` () = // do t.Result // x |> equal 2 +[] +let ``Async.Sleep works`` () = + let mutable s = "" + let a1 = + async { + do! Async.Sleep(200) + s <- s + "200" + } + let a2 = + async { + do! Async.Sleep(100) + s <- s + "100" + } + let t1 = a1 |> Async.StartAsTask + let t2 = a2 |> Async.StartAsTask + let r1 = t1.Result + let r2 = t2.Result + s |> equal "100200" // type DisposableAction(f) = // interface IDisposable with @@ -588,7 +605,6 @@ let ``Lock should return result`` () = // Async.StartWithContinuations(work, (fun r -> result <- r), ignore, ignore) // equal result 42 - // [] // let ``Deep recursion with async doesn't cause stack overflow`` () = // async { @@ -744,7 +760,7 @@ let ``Lock should return result`` () = // |> Async.StartImmediate // [] -// let ``Async.StartChild applys timeout`` () = +// let ``Async.StartChild applies timeout`` () = // async { // let mutable x = "" // let task = async { diff --git a/tests/Rust/tests/src/TypeTests.fs b/tests/Rust/tests/src/TypeTests.fs index 2ce0909ef1..905753deef 100644 --- a/tests/Rust/tests/src/TypeTests.fs +++ b/tests/Rust/tests/src/TypeTests.fs @@ -119,17 +119,17 @@ let inline show< ^T when ^T : (member show : unit -> string)> (x:^T) : string = let inline showStatic< ^T when ^T : (static member show : ^T -> string)> (x:^T) : string = (^T : (static member show : ^T -> string) (x)) -// [] -// type Serializable(?i: int) = -// let mutable deserialized = false -// let mutable publicValue = 1 -// let mutable privateValue = defaultArg i 0 -// member x.PublicValue -// with get() = publicValue -// and set(i) = deserialized <- true; publicValue <- i -// override x.ToString() = -// sprintf "Public: %i - Private: %i - Deserialized: %b" -// publicValue privateValue deserialized +[] +type Serializable(?i: int) = + let mutable deserialized = false + let mutable publicValue = 1 + let mutable privateValue = defaultArg i 0 + member x.PublicValue + with get() = publicValue + and set(i) = deserialized <- true; publicValue <- i + override x.ToString() = + sprintf "Public: %i - Private: %i - Deserialized: %b" + publicValue privateValue deserialized type SecondaryCons(x: int) = new () = SecondaryCons(5)