sea-orm-ffi 0.1.3

Compatibility layer for Sea-ORM when crossing a Rust-to-Rust FFI boundary
Documentation
/// Macro to create an optional type for a pointer type.
#[doc(hidden)]
#[macro_export]
macro_rules! option {
	($ident:ident $(<$generic:ident>)?) => {
		paste::paste! {
			#[repr(transparent)]
			pub(crate) struct [< Optional $ident >]$(<$generic>)?(
				std::mem::ManuallyDrop<$ident$(<$generic>)?>
			);

			impl$(<$generic>)? [< Optional $ident >]$(<$generic>)? {
				pub(crate) fn some<Value>(value: Value) -> Self
				where
					Value: Into<$ident$(<$generic>)?>
				{
					Self(std::mem::ManuallyDrop::new(value.into()))
				}

				pub(crate) fn none() -> Self {
					Self(std::mem::ManuallyDrop::new($ident {
						ptr: std::ptr::null_mut(),
						len: 0,
						cap: 0
					}))
				}

				pub(crate) fn is_none(&self) -> bool {
					self.0.ptr.is_null()
				}

				pub(crate) fn is_some(&self) -> bool {
					!self.is_none()
				}

				pub(crate) fn into_option<Value>(mut self) -> Option<Value>
				where
					Value: From<$ident$(<$generic>)?>
				{
					if self.is_none() {
						None
					} else {
						// Safety: We are replacing the pointer with a null pointer,
						// so the Drop impl will not drop it twice
						unsafe {
							let inner = std::mem::ManuallyDrop::take(&mut self.0);
							self.0.ptr = std::ptr::null_mut();
							Some(inner.into())
						}
					}
				}
			}

			impl<$($generic,)? Value> From<Option<Value>> for [< Optional $ident >]$(<$generic>)?
			where
				Value: Into<$ident$(<$generic>)?>
			{
				fn from(value: Option<Value>) -> Self {
					value.map(Self::some).unwrap_or_else(Self::none)
				}
			}

			impl<$($generic,)? Value> From<[< Optional $ident >]$(<$generic>)?> for Option<Value>
			where
				Value: From<$ident$(<$generic>)?>
			{
				fn from(value: [< Optional $ident >]$(<$generic>)?) -> Self {
					value.into_option()
				}
			}

			impl$(<$generic>)? Drop for [< Optional $ident >]$(<$generic>)? {
				fn drop(&mut self) {
					if self.is_some() {
						unsafe {
							std::mem::ManuallyDrop::drop(&mut self.0);
						}
					}
				}
			}
		}
	};
}