dittolive_ditto/utils/
mod.rs

1#[macro_use]
2pub mod macros;
3
4pub mod prelude;
5
6use ffi_sdk::ffi_utils::ReprC;
7use safer_ffi::closure::BoxDynFnMut1;
8pub(crate) use set_arc::SetArc;
9use tokio::sync::oneshot;
10mod set_arc;
11
12pub(crate) mod zstr;
13
14pub(crate) mod extension_traits;
15pub type Str = ::std::borrow::Cow<'static, str>;
16
17#[derive(Default)]
18pub struct InvariantLifetimeMarker<'lifetime>(
19    ::core::marker::PhantomData<&'lifetime mut &'lifetime ()>,
20);
21
22pub fn base64_encode_unpadded(bytes: &[u8]) -> String {
23    ::base64::Engine::encode(&::base64::engine::general_purpose::URL_SAFE_NO_PAD, bytes)
24}
25
26pub fn base64_decode_unpadded(str: &str) -> Result<Box<[u8]>, ::base64::DecodeError> {
27    let v = ::base64::Engine::decode(&::base64::engine::general_purpose::URL_SAFE_NO_PAD, str)?;
28    Ok(v.into_boxed_slice())
29}
30
31pub(crate) fn make_continuation<T>() -> (BoxDynFnMut1<(), T>, oneshot::Receiver<T>)
32where
33    T: ReprC + Send + 'static,
34{
35    let (send, recv) = oneshot::channel();
36
37    // `move` forces the closure to take ownership of `send`, which we make into an `Option<Sender>`
38    // Then, in the callback, since it can only implement `FnMut`, we can use `Option::take` to get
39    // ownership of the sender even though we only have a `&mut Option`. If the option is none,
40    // that means that we've already run the function once
41    let mut send = Some(send);
42    let continuation = BoxDynFnMut1::new(Box::new(move |result| {
43        let Some(send) = send.take() else {
44            panic!("This callback has been called twice, but it is morally a `BoxDynFnOnce1`")
45        };
46
47        // no .unwrap() to avoid `T: Debug` bound
48        if send.send(result).is_err() {
49            panic!("failed to send in BoxDynFnMut1");
50        }
51    }));
52
53    (continuation, recv)
54}