Skip to content

Commit

Permalink
make impl_guarded_transmute automatically implement From, Deref and D…
Browse files Browse the repository at this point in the history
…erefMut traits
  • Loading branch information
DenisBiryukov91 committed Mar 28, 2024
1 parent db9733e commit de1f606
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 165 deletions.
2 changes: 1 addition & 1 deletion src/attachment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub struct z_owned_bytes_map_t {
_1: [usize; 4],
}

impl_guarded_transmute!(
impl_guarded_transmute!(noderefs
Option<HashMap<Cow<'static, [u8]>, Cow<'static, [u8]>>>,
z_owned_bytes_map_t
);
Expand Down
14 changes: 0 additions & 14 deletions src/commons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,6 @@ pub extern "C" fn zc_payload_null() -> zc_owned_payload_t {
pub struct z_qos_t(u8);

impl_guarded_transmute!(QoS, z_qos_t);
impl_guarded_transmute!(z_qos_t, QoS);

impl From<QoS> for z_qos_t {
fn from(qos: QoS) -> Self {
qos.transmute()
}
}

impl From<z_qos_t> for QoS {
fn from(qos: z_qos_t) -> QoS {
qos.transmute()
}
}

/// Returns message priority.
#[no_mangle]
pub extern "C" fn z_qos_get_priority(qos: z_qos_t) -> z_priority_t {
Expand Down
7 changes: 1 addition & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use libc::{c_char, c_uint};
use std::ffi::CStr;
use zenoh::config::{Config, ValidatedMap, WhatAmI};

use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null, GuardedTransmute};
use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null};

#[no_mangle]
pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint;
Expand Down Expand Up @@ -76,11 +76,6 @@ pub struct z_config_t(*const z_owned_config_t);
pub struct z_owned_config_t(*mut ());
impl_guarded_transmute!(Option<Box<Config>>, z_owned_config_t);

impl From<Option<Box<Config>>> for z_owned_config_t {
fn from(v: Option<Box<Config>>) -> Self {
v.transmute()
}
}
/// Returns a :c:type:`z_config_t` loaned from `s`.
#[no_mangle]
pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t {
Expand Down
2 changes: 1 addition & 1 deletion src/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct z_owned_reply_t([u64; 30]);
#[repr(C, align(8))]
pub struct z_owned_reply_t([u64; 19]);

impl_guarded_transmute!(ReplyInner, z_owned_reply_t);
impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t);

impl From<ReplyInner> for z_owned_reply_t {
fn from(mut val: ReplyInner) -> Self {
Expand Down
20 changes: 2 additions & 18 deletions src/keyexpr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,11 @@ pub struct z_owned_keyexpr_t([u32; 5]);

impl_guarded_transmute!(Option<KeyExpr<'static>>, z_owned_keyexpr_t);

impl From<Option<KeyExpr<'static>>> for z_owned_keyexpr_t {
fn from(val: Option<KeyExpr<'static>>) -> Self {
val.transmute()
}
}
impl From<KeyExpr<'static>> for z_owned_keyexpr_t {
fn from(val: KeyExpr<'static>) -> Self {
Some(val).into()
}
}
impl Deref for z_owned_keyexpr_t {
type Target = Option<KeyExpr<'static>>;
fn deref(&self) -> &Self::Target {
unsafe { std::mem::transmute(self) }
}
}
impl DerefMut for z_owned_keyexpr_t {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { std::mem::transmute(self) }
}
}
impl z_owned_keyexpr_t {
pub fn null() -> Self {
None::<KeyExpr>.into()
Expand Down Expand Up @@ -183,8 +167,8 @@ pub struct z_keyexpr_t([u64; 4]);
#[repr(C, align(4))]
pub struct z_keyexpr_t([u32; 5]);

impl_guarded_transmute!(Option<KeyExpr<'_>>, z_keyexpr_t);
impl_guarded_transmute!(z_keyexpr_t, z_owned_keyexpr_t);
impl_guarded_transmute!(noderefs Option<KeyExpr<'_>>, z_keyexpr_t);
impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t);

impl<'a> From<KeyExpr<'a>> for z_keyexpr_t {
fn from(val: KeyExpr<'a>) -> Self {
Expand Down
54 changes: 53 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,37 @@ trait GuardedTransmute<D> {
fn transmute(self) -> D;
}

/// For internal use only.
///
/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter).
///
/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types.
///
/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are
/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined.
#[macro_export]
macro_rules! impl_guarded_transmute {
($src_type:ty, $dst_type:ty) => {
impl_guarded_transmute!(noderefs $src_type, $dst_type);
impl From<$src_type> for $dst_type {
fn from(value: $src_type) -> $dst_type {
unsafe { core::mem::transmute(value) }
}
}
impl core::ops::Deref for $dst_type {
type Target = $src_type;
fn deref(&self) -> &$src_type {
unsafe { core::mem::transmute(self) }
}
}
impl core::ops::DerefMut for $dst_type {
fn deref_mut(&mut self) -> &mut $src_type {
unsafe { core::mem::transmute(self) }
}
}

};
(noderefs $src_type:ty, $dst_type:ty) => {
const _: () = {
let src = std::mem::align_of::<$src_type>();
let dst = std::mem::align_of::<$dst_type>();
Expand All @@ -81,12 +109,36 @@ macro_rules! impl_guarded_transmute {
});
}
};
impl $crate::GuardedTransmute<$dst_type> for $src_type {
impl $crate::GuardedTransmute<$dst_type> for $src_type {
fn transmute(self) -> $dst_type {
unsafe { std::mem::transmute::<$src_type, $dst_type>(self) }
}
}
};
($src_type:ty, $dst_type:ty, $($gen: tt)*) => {
impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type {
fn transmute(self) -> $dst_type {
unsafe { std::mem::transmute::<$src_type, $dst_type>(self) }
}
}
impl<$($gen)*> From<$src_type> for $dst_type {
fn from(value: $src_type) -> $dst_type {
unsafe { core::mem::transmute(value) }
}
}
impl<$($gen)*> core::ops::Deref for $dst_type {
type Target = $src_type;
fn deref(&self) -> &$src_type {
unsafe { core::mem::transmute(self) }
}
}
impl<$($gen)*> core::ops::DerefMut for $dst_type {
fn deref_mut(&mut self) -> &mut $src_type {
unsafe { core::mem::transmute(self) }
}
}

};
}

pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session";
Expand Down
12 changes: 6 additions & 6 deletions src/platform/synchronization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub struct ZMutexPtr {
#[derive(Clone, Copy)]
pub struct z_mutex_t(usize);

impl_guarded_transmute!(z_mutex_t, ZMutexPtr);
impl_guarded_transmute!(ZMutexPtr, z_mutex_t);
impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr);
impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t);

// using the same error codes as in GNU pthreads, but with negative sign
// due to convention to return negative values on error
Expand Down Expand Up @@ -141,8 +141,8 @@ struct ZCondvarPtr {
#[derive(Clone, Copy)]
pub struct z_condvar_t(usize);

impl_guarded_transmute!(z_condvar_t, ZCondvarPtr);
impl_guarded_transmute!(ZCondvarPtr, z_condvar_t);
impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr);
impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t);

#[no_mangle]
#[allow(clippy::missing_safety_doc)]
Expand Down Expand Up @@ -233,8 +233,8 @@ pub struct z_task_t(usize);
#[derive(Clone, Copy)]
pub struct z_task_attr_t(usize);

impl_guarded_transmute!(z_task_t, ZTaskPtr);
impl_guarded_transmute!(ZTaskPtr, z_task_t);
impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr);
impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t);

struct FunArgPair {
fun: unsafe extern "C" fn(arg: *mut c_void),
Expand Down
23 changes: 2 additions & 21 deletions src/publication_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ use zenoh_util::core::zresult::ErrNo;
use zenoh_util::core::SyncResolve;

use crate::{
impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t,
GuardedTransmute, UninitializedKeyExprError,
impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, UninitializedKeyExprError,
};

/// Options passed to the :c:func:`ze_declare_publication_cache` function.
Expand Down Expand Up @@ -70,24 +69,6 @@ pub struct ze_owned_publication_cache_t([usize; 1]);

impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t);

impl From<PublicationCache> for ze_owned_publication_cache_t {
fn from(val: PublicationCache) -> Self {
val.transmute()
}
}

impl AsRef<PublicationCache> for ze_owned_publication_cache_t {
fn as_ref(&self) -> &PublicationCache {
unsafe { std::mem::transmute(self) }
}
}

impl AsMut<PublicationCache> for ze_owned_publication_cache_t {
fn as_mut(&mut self) -> &mut PublicationCache {
unsafe { std::mem::transmute(self) }
}
}

impl ze_owned_publication_cache_t {
pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self {
Some(Box::new(pub_cache)).into()
Expand Down Expand Up @@ -187,7 +168,7 @@ pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_ca
pub extern "C" fn ze_undeclare_publication_cache(
pub_cache: &mut ze_owned_publication_cache_t,
) -> i8 {
if let Some(p) = pub_cache.as_mut().take() {
if let Some(p) = pub_cache.take() {
if let Err(e) = p.close().res_sync() {
log::error!("{}", e);
return e.errno().get();
Expand Down
4 changes: 2 additions & 2 deletions src/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub struct z_owned_publisher_t([u64; 7]);
#[repr(C, align(4))]
pub struct z_owned_publisher_t([u32; 8]);

impl_guarded_transmute!(Option<Publisher<'_>>, z_owned_publisher_t);
impl_guarded_transmute!(noderefs Option<Publisher<'_>>, z_owned_publisher_t);

impl<'a> From<Option<Publisher<'a>>> for z_owned_publisher_t {
fn from(val: Option<Publisher>) -> Self {
Expand Down Expand Up @@ -387,7 +387,7 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyex
#[repr(C, align(8))]
pub struct zcu_owned_matching_listener_t([u64; 4]);

impl_guarded_transmute!(
impl_guarded_transmute!(noderefs
Option<MatchingListener<'_, ()>>,
zcu_owned_matching_listener_t
);
Expand Down
15 changes: 1 addition & 14 deletions src/pull_subscriber.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::GuardedTransmute;
//
// Copyright (c) 2017, 2022 ZettaScale Technology.
//
Expand Down Expand Up @@ -56,21 +55,9 @@ impl_guarded_transmute!(PullSubscriber, z_owned_pull_subscriber_t);
#[allow(non_camel_case_types)]
pub struct z_pull_subscriber_t<'a>(&'a z_owned_pull_subscriber_t);

impl From<PullSubscriber> for z_owned_pull_subscriber_t {
fn from(val: PullSubscriber) -> Self {
val.transmute()
}
}

impl AsRef<PullSubscriber> for z_owned_pull_subscriber_t {
fn as_ref(&self) -> &PullSubscriber {
unsafe { std::mem::transmute(self) }
}
}

impl<'a> AsRef<PullSubscriber> for z_pull_subscriber_t<'a> {
fn as_ref(&self) -> &PullSubscriber {
self.0.as_ref()
self.0
}
}

Expand Down
20 changes: 2 additions & 18 deletions src/queryable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::attachment::{
};
use crate::{
impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t,
z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, GuardedTransmute,
z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t,
LOG_INVALID_SESSION,
};
use libc::c_void;
Expand Down Expand Up @@ -52,22 +52,6 @@ pub struct z_owned_queryable_t([u32; 4]);

impl_guarded_transmute!(Queryable, z_owned_queryable_t);

impl From<Queryable> for z_owned_queryable_t {
fn from(val: Queryable) -> Self {
val.transmute()
}
}
impl AsRef<Queryable> for z_owned_queryable_t {
fn as_ref(&self) -> &Queryable {
unsafe { std::mem::transmute(self) }
}
}
impl AsMut<Queryable> for z_owned_queryable_t {
fn as_mut(&mut self) -> &mut Queryable {
unsafe { std::mem::transmute(self) }
}
}

impl z_owned_queryable_t {
pub fn null() -> Self {
None.into()
Expand Down Expand Up @@ -263,7 +247,7 @@ pub extern "C" fn z_declare_queryable(
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 {
if let Some(qable) = qable.as_mut().take() {
if let Some(qable) = qable.take() {
if let Err(e) = qable.undeclare().res_sync() {
log::error!("{}", e);
return e.errno().get();
Expand Down
26 changes: 4 additions & 22 deletions src/querying_subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ use crate::{
z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t,
z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t,
zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t,
GuardedTransmute, LOG_INVALID_SESSION,
LOG_INVALID_SESSION,
};

struct FetchingSubscriberWrapper {
pub struct FetchingSubscriberWrapper {
fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>,
session: z_session_t,
}
Expand All @@ -54,27 +54,9 @@ impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t);
#[allow(non_camel_case_types)]
pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t);

impl From<FetchingSubscriber> for ze_owned_querying_subscriber_t {
fn from(val: FetchingSubscriber) -> Self {
val.transmute()
}
}

impl AsRef<FetchingSubscriber> for ze_owned_querying_subscriber_t {
fn as_ref(&self) -> &FetchingSubscriber {
unsafe { std::mem::transmute(self) }
}
}

impl<'a> AsRef<FetchingSubscriber> for ze_querying_subscriber_t<'a> {
fn as_ref(&self) -> &FetchingSubscriber {
self.0.as_ref()
}
}

impl AsMut<FetchingSubscriber> for ze_owned_querying_subscriber_t {
fn as_mut(&mut self) -> &mut FetchingSubscriber {
unsafe { std::mem::transmute(self) }
self.0
}
}

Expand Down Expand Up @@ -276,7 +258,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get(
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 {
if let Some(s) = sub.as_mut().take() {
if let Some(s) = sub.take() {
if let Err(e) = s.fetching_subscriber.close().res_sync() {
log::warn!("{}", e);
return e.errno().get();
Expand Down
Loading

0 comments on commit de1f606

Please sign in to comment.