clt_database/turso_sdk_kit/src/
lib.rs1use std::sync::atomic::{AtomicU32, Ordering};
2
3use crate::turso_sdk_kit::rsapi::TursoError;
4
5pub mod capi;
6pub mod rsapi;
7
8#[macro_export]
9macro_rules! assert_send {
10 ($($ty:ty),+ $(,)?) => {
11 const _: fn() = || {
12 fn check<T: Send>() {}
13 $( check::<$ty>(); )+
14 };
15 };
16}
17
18#[macro_export]
19macro_rules! assert_sync {
20 ($($ty:ty),+ $(,)?) => {
21 const _: fn() = || {
22 fn check<T: Sync>() {}
23 $( check::<$ty>(); )+
24 };
25 };
26}
27
28struct ConcurrentGuard {
30 in_use: AtomicU32,
31}
32
33struct ConcurrentGuardToken<'a> {
34 guard: &'a ConcurrentGuard,
35}
36
37impl ConcurrentGuard {
38 pub fn new() -> Self {
39 Self {
40 in_use: AtomicU32::new(0),
41 }
42 }
43 pub fn try_use(&self) -> Result<ConcurrentGuardToken<'_>, TursoError> {
44 if self
45 .in_use
46 .compare_exchange(0, 1, Ordering::SeqCst, Ordering::SeqCst)
47 .is_err()
48 {
49 return Err(TursoError::Misuse("concurrent use forbidden".to_string()));
50 };
51 Ok(ConcurrentGuardToken { guard: self })
52 }
53}
54
55impl<'a> Drop for ConcurrentGuardToken<'a> {
56 fn drop(&mut self) {
57 let before = self.guard.in_use.swap(0, Ordering::SeqCst);
58 assert!(
59 before == 1,
60 "invalid db state: guard wasn't in use while token is active"
61 );
62 }
63}
64
65pub use crate::{assert_send, assert_sync};