I made a
TigerBeetle
Rust client
I got mad about software dependencies.
I did an experiment about it.



async / await
pub fn lookup_transfers(
&self,
events: &[u128],
) -> impl Future<...> {
let (packet, rx) = create_packet(
TB_OPERATION_LOOKUP_TRANSFERS,
events,
);
unsafe {
tb_client_submit(
self.client,
Box::into_raw(packet),
);
}
async {
let msg = rx.await?;
let responses = handle_message(&msg)?;
Ok(Vec::from(responses))
}
}
N = N-1
cargo +N test
Initial MSRV
Rust 1.81
September 5, 2024
yikes
tigerbeetle/docs/TIGER_STYLE.md
[dependencies]
bitflags = "2.6.0"
futures = "0.3.31"
thiserror = "2.0.3"
[build-dependencies]
anyhow = "1.0.93"
ignore = "0.4.23"
[dev-dependencies]
anyhow = "1.0.93"
tempfile = "3.15.0"
futures futures v0.3.31
├── futures-channel v0.3.31
│ ├── futures-core v0.3.31
│ └── futures-sink v0.3.31
├── futures-core v0.3.31
├── futures-executor v0.3.31
│ ├── futures-core v0.3.31
│ ├── futures-task v0.3.31
│ └── futures-util v0.3.31
│ ├── futures-channel v0.3.31 (*)
│ ├── futures-core v0.3.31
│ ├── futures-io v0.3.31
│ ├── futures-macro v0.3.31 (proc-macro)
│ │ ├── proc-macro2 v1.0.90
│ │ │ └── unicode-ident v1.0.14
│ │ ├── quote v1.0.37
│ │ │ └── proc-macro2 v1.0.90 (*)
│ │ └── syn v2.0.88
│ │ ├── proc-macro2 v1.0.90 (*)
│ │ ├── quote v1.0.37 (*)
│ │ └── unicode-ident v1.0.14
│ ├── futures-sink v0.3.31
│ ├── futures-task v0.3.31
│ ├── memchr v2.7.4
│ ├── pin-project-lite v0.2.15
│ ├── pin-utils v0.1.0
│ └── slab v0.4.9
├── futures-io v0.3.31
├── futures-sink v0.3.31
├── futures-task v0.3.31
└── futures-util v0.3.31 (*)
| serde | anyhow | ||
| futures | syn | ||
| rayon | walkdir | ||
| etc. | |||
| serde | 1.31 | anyhow | 1.38 |
| futures | 1.68 | syn | 1.68 |
| rayon | 1.80 | walkdir | 1.31 |
fs::existsfutures / syn / proc-macro2
bitflags, edition 2018matches!, u64::MAXasync/await minimumsyn / proc-macro2
The minimum Rust version
supported by
most of the Rust
ecosystem is limited by the
syn and proc-macro2 crates.
futures Dependency
[dependencies]
futures = "0.3.31"
[dependencies]
futures-channel = "0.3.31"
[dev-dependencies]
futures-executor = "0.3.31"
futures-util = "0.3.31"
block_onpub fn block_on<F: Future>(future: F) -> F::Output {
let mut future = Box::pin(future);
let parker = Arc::new(Parker::new());
let waker = parker_into_waker(parker.clone());
let mut context = Context::from_waker(&waker);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(result) => return result,
Poll::Pending => parker.park(),
}
}
}
// Reimplemented from futures-util:
pub trait Stream { ... } // 8 lines
pub trait StreamExt { ... } // 12 lines
pub struct Next<'a, S> { ... } // 15 lines
pub fn unfold<T, F, Fut, Item> // 45 lines
pub struct Unfold<T, F, Fut> // 35 lines
macro_rules! pin_mut! { ... } // 10 lines
struct OneshotFuture<T> { shared: Arc<OneshotShared<T>> }
struct OneshotShared<T> { waker: Mutex<Option<Waker>>,
value: Mutex<Option<T>> }
struct OneshotSender<T> { shared: Arc<OneshotShared<T>> }
impl<T> Future for OneshotFuture<T> { /* 12 lines */ }
impl<T> OneshotSender<T> { fn send(self, value: T) { /* 10 lines */ } }
Java doesn't seem to have this problem.
Modules introduced 1.13, September 19.
~60% compatibility.