swift_rs/
swift_arg.rs

1use std::ffi::c_void;
2
3use crate::{swift::SwiftObject, *};
4
5/// Identifies a type as being a valid argument in a Swift function.
6pub trait SwiftArg<'a> {
7    type ArgType;
8
9    /// Creates a swift-compatible version of the argument.
10    /// For primitives this just returns `self`,
11    /// but for [`SwiftObject`] types it wraps them in [`SwiftRef`].
12    ///
13    /// This function is called within the [`swift!`] macro.
14    ///
15    /// # Safety
16    ///
17    /// Creating a [`SwiftRef`] is inherently unsafe,
18    /// but is reliable if using the [`swift!`] macro,
19    /// so it is not advised to call this function manually.
20    unsafe fn as_arg(&'a self) -> Self::ArgType;
21}
22
23macro_rules! primitive_impl {
24    ($($t:ty),+) => {
25        $(impl<'a> SwiftArg<'a> for $t {
26            type ArgType = $t;
27
28            unsafe fn as_arg(&'a self) -> Self::ArgType {
29                *self
30            }
31        })+
32    };
33}
34
35primitive_impl!(
36    Bool,
37    Int,
38    Int8,
39    Int16,
40    Int32,
41    Int64,
42    UInt,
43    UInt8,
44    UInt16,
45    UInt32,
46    UInt64,
47    Float32,
48    Float64,
49    *const c_void,
50    *mut c_void,
51    *const u8,
52    ()
53);
54
55macro_rules! ref_impl {
56    ($($t:ident $(<$($gen:ident),+>)?),+) => {
57        $(impl<'a $($(, $gen: 'a),+)?> SwiftArg<'a> for $t$(<$($gen),+>)? {
58            type ArgType = SwiftRef<'a, $t$(<$($gen),+>)?>;
59
60            unsafe fn as_arg(&'a self) -> Self::ArgType {
61                self.swift_ref()
62            }
63        })+
64    };
65}
66
67ref_impl!(SRObject<T>, SRArray<T>, SRData, SRString);
68
69impl<'a, T: SwiftArg<'a>> SwiftArg<'a> for &T {
70    type ArgType = T::ArgType;
71
72    unsafe fn as_arg(&'a self) -> Self::ArgType {
73        (*self).as_arg()
74    }
75}