bisync/
lib.rs

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