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
use super::error::CBError;
use std::future::Future;
use std::cell::RefCell;
use std::fmt::Debug;
use std::{io, pin::Pin};
use tokio::runtime::Runtime;
pub trait Adapter<T> {
type Result: Sized;
fn process<F>(&self, f: F) -> Self::Result
where
F: Future<Output = Result<T, CBError>> + Send + 'static;
}
pub trait AdapterNew: Sized {
type Error: Debug;
fn new() -> Result<Self, Self::Error>;
}
pub struct Sync(RefCell<Runtime>);
impl AdapterNew for Sync {
type Error = io::Error;
fn new() -> Result<Self, Self::Error> {
Ok(Sync(RefCell::new(Runtime::new()?)))
}
}
impl<T> Adapter<T> for Sync
where
T: Send + 'static,
{
type Result = Result<T, CBError>;
fn process<F>(&self, f: F) -> Self::Result
where
F: Future<Output = Result<T, CBError>> + Send + 'static,
{
self.0.borrow_mut().block_on(f)
}
}
pub struct ASync;
impl AdapterNew for ASync {
type Error = ();
fn new() -> Result<Self, Self::Error> {
Ok(ASync)
}
}
impl<T> Adapter<T> for ASync {
type Result = Pin<Box<dyn Future<Output = Result<T, CBError>> + Send>>;
fn process<F>(&self, f: F) -> Self::Result
where
F: Future<Output = Result<T, CBError>> + Send + 'static,
{
Box::pin(f)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{utils::delay, Public, SANDBOX_URL};
use futures::{future, TryFutureExt};
#[test]
#[serial]
fn test_sync() {
delay();
let client: Public<Sync> = Public::new(SANDBOX_URL);
let time = client.get_time().unwrap();
let time_str = format!("{:?}", time);
assert!(time_str.starts_with("Time {"));
assert!(time_str.contains("iso:"));
assert!(time_str.contains("epoch:"));
assert!(time_str.ends_with("}"));
}
#[test]
#[serial]
fn test_async() {
delay();
let client: Public<ASync> = Public::new(SANDBOX_URL);
let time = client.get_time().and_then(|time| {
let time_str = format!("{:?}", time);
assert!(time_str.starts_with("Time {"));
assert!(time_str.contains("iso:"));
assert!(time_str.contains("epoch:"));
assert!(time_str.ends_with("}"));
future::ready(Ok(()))
});
let rt = Runtime::new().unwrap();
rt.block_on(time).ok();
}
}