1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! This crate can be used to easily write code for synchronous as well as asynchronous clients.
//!
//! The use should be straight-forward.
//! You can put this into your file where you'd like to have both synchronous and asynchronous submodules:
//!
//! ```
//! // lib.rs
//!
//! #[path = "."]
//! pub mod asynchronous {
//! use bisync::asynchronous::*;
//! mod inner;
//! pub use inner::*;
//! }
//!
//! // here you could also add `#[cfg]` attributes to enable or disable this module
//! #[path = "."]
//! pub mod blocking {
//! use bisync::synchronous::*;
//! mod inner;
//! pub use inner::*;
//! }
//! ```
//! (The reason why I recommend to copy-paste this instead of providing a macro that does it for you is because LSPs struggle with modules defined within macros)
//!
//! Then, within your `inner` module, you can write code that is async-generic:
//! ```
//! // inner.rs
//!
//! // these are all the available definitions:
//! use super::{bisync, only_sync, only_async, SYNC, ASYNC};
//!
//! #[bisync]
//! pub async fn foo() -> String {
//! bar().await
//! }
//!
//! #[bisync]
//! async fn bar() -> String {
//! if ASYNC {
//! println!("We are in async code.");
//! } else if SYNC {
//! println!("We are in blocking code.");
//! } else {
//! panic!("This is neither async nor blocking code but a secret third thing.");
//! }
//!
//! baz().await
//! }
//!
//! #[only_sync]
//! fn baz() -> String {
//! ureq::get("https://example.com")
//! .call()
//! .unwrap()
//! .into_string()
//! .unwrap()
//! }
//!
//! #[only_async]
//! async fn baz() -> String {
//! reqwest::get("https://example.com")
//! .await
//! .unwrap()
//! .text()
//! .await
//! .unwrap()
//! }
//! ```
//!
//! Here, depending on if we are within async or sync code, we use a different library to perform the requests.
//! As you can see, we prevent duplicate definitions of `foo` and `bar` because they get generated twice,
//! once in synchronous form, and once in asynchronous form.
//!
/// The definitions to use for the synchronous code variation
/// The definitions to use for the asynchronous code variation