matrix_sdk_ffi/
utils.rs

1// Copyright 2023 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{mem::ManuallyDrop, ops::Deref};
16
17use ruma::{MilliSecondsSinceUnixEpoch, UInt};
18use tracing::warn;
19
20use crate::runtime::get_runtime_handle;
21
22#[derive(Debug, Clone)]
23pub struct Timestamp(u64);
24
25impl From<MilliSecondsSinceUnixEpoch> for Timestamp {
26    fn from(date: MilliSecondsSinceUnixEpoch) -> Self {
27        Self(date.0.into())
28    }
29}
30
31uniffi::custom_newtype!(Timestamp, u64);
32
33pub(crate) fn u64_to_uint(u: u64) -> UInt {
34    UInt::new(u).unwrap_or_else(|| {
35        warn!("u64 -> UInt conversion overflowed, falling back to UInt::MAX");
36        UInt::MAX
37    })
38}
39
40/// Tiny wrappers for data types that must be dropped in the context of an async
41/// runtime.
42///
43/// This is useful whenever such a data type may transitively call some
44/// runtime's `block_on` function in their `Drop` impl (since we lack async drop
45/// at the moment), like done in some `deadpool` drop impls.
46pub(crate) struct AsyncRuntimeDropped<T>(ManuallyDrop<T>);
47
48impl<T> AsyncRuntimeDropped<T> {
49    /// Create a new wrapper for this type that will be dropped under an async
50    /// runtime.
51    pub fn new(val: T) -> Self {
52        Self(ManuallyDrop::new(val))
53    }
54}
55
56impl<T> Drop for AsyncRuntimeDropped<T> {
57    fn drop(&mut self) {
58        let _guard = get_runtime_handle().enter();
59        // SAFETY: self.inner is never used again, which is the only requirement
60        //         for ManuallyDrop::drop to be used safely.
61        unsafe {
62            ManuallyDrop::drop(&mut self.0);
63        }
64    }
65}
66
67// What is an `AsyncRuntimeDropped<T>`, if not a `T` in disguise?
68impl<T> Deref for AsyncRuntimeDropped<T> {
69    type Target = T;
70
71    fn deref(&self) -> &Self::Target {
72        &self.0
73    }
74}
75
76impl<T: Clone> Clone for AsyncRuntimeDropped<T> {
77    fn clone(&self) -> Self {
78        Self(self.0.clone())
79    }
80}