atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git
bindings/matrix-sdk-ffi/src/utils.rsRust80 lines2.4 KB
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
15
use std::{mem::ManuallyDrop, ops::Deref};
16
17
use ruma::{MilliSecondsSinceUnixEpoch, UInt};
18
use tracing::warn;
19
20
use crate::runtime::get_runtime_handle;
21
22
#[derive(Debug, Clone)]
23
pub struct Timestamp(u64);
24
25
impl From<MilliSecondsSinceUnixEpoch> for Timestamp {
26
    fn from(date: MilliSecondsSinceUnixEpoch) -> Self {
27
        Self(date.0.into())
28
    }
29
}
30
31
uniffi::custom_newtype!(Timestamp, u64);
32
33
pub(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.
46
pub(crate) struct AsyncRuntimeDropped<T>(ManuallyDrop<T>);
47
48
impl<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
56
impl<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?
68
impl<T> Deref for AsyncRuntimeDropped<T> {
69
    type Target = T;
70
71
    fn deref(&self) -> &Self::Target {
72
        &self.0
73
    }
74
}
75
76
impl<T: Clone> Clone for AsyncRuntimeDropped<T> {
77
    fn clone(&self) -> Self {
78
        Self(self.0.clone())
79
    }
80
}