use std::fmt;
use rdma_sys::ibv_gid;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy)]
#[repr(transparent)]
pub(crate) struct Gid(ibv_gid);
#[allow(dead_code)]
impl Gid {
fn from_raw(raw: [u8; 16]) -> Self {
Self(ibv_gid { raw })
}
fn as_raw(&self) -> &[u8; 16] {
unsafe { &self.0.raw }
}
fn subnet_prefix(&self) -> u64 {
unsafe { u64::from_be(self.0.global.subnet_prefix) }
}
fn interface_id(&self) -> u64 {
unsafe { u64::from_be(self.0.global.interface_id) }
}
}
impl fmt::Debug for Gid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Gid").field(self.as_raw()).finish()
}
}
impl PartialEq for Gid {
fn eq(&self, other: &Self) -> bool {
self.as_raw() == other.as_raw()
}
}
impl Eq for Gid {}
impl From<ibv_gid> for Gid {
fn from(gid: ibv_gid) -> Self {
Self(gid)
}
}
impl From<Gid> for ibv_gid {
#[inline]
fn from(gid: Gid) -> Self {
gid.0
}
}
impl AsRef<ibv_gid> for Gid {
fn as_ref(&self) -> &ibv_gid {
unsafe { &*<*const Self>::cast::<ibv_gid>(self) }
}
}
impl AsMut<ibv_gid> for Gid {
fn as_mut(&mut self) -> &mut ibv_gid {
unsafe { &mut *<*mut Self>::cast::<ibv_gid>(self) }
}
}
impl Serialize for Gid {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
<[u8; 16] as Serialize>::serialize(self.as_raw(), serializer)
}
}
impl<'de> Deserialize<'de> for Gid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
<[u8; 16] as Deserialize<'de>>::deserialize(deserializer).map(Self::from_raw)
}
}
#[test]
fn repr_check() {
use std::mem::{align_of, size_of};
assert_eq!(size_of::<Gid>(), size_of::<ibv_gid>());
assert_eq!(align_of::<Gid>(), align_of::<ibv_gid>());
}