Skip to content

Commit

Permalink
argconv: make FFI implementation mutually exclusive
Browse files Browse the repository at this point in the history
Disallow implementing two different APIs for specific type.
  • Loading branch information
muzarski committed Dec 2, 2024
1 parent 39d51fe commit e8d2d93
Show file tree
Hide file tree
Showing 19 changed files with 114 additions and 32 deletions.
28 changes: 25 additions & 3 deletions scylla-rust-wrapper/src/argconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,18 @@ impl<T: Sized> CassPtr<T, (Borrowed, Const)> {
}
}

mod own_sealed {
pub trait ExclusiveSealed {}
pub trait SharedSealed {}
pub trait BorrowedSealed {}
}

/// Defines a pointer manipulation API for non-shared heap-allocated data.
///
/// Implement this trait for types that are allocated by the driver via [`Box::new`],
/// and then returned to the user as a pointer. The user is responsible for freeing
/// the memory associated with the pointer using corresponding driver's API function.
pub trait BoxFFI: Sized {
pub trait BoxFFI: Sized + own_sealed::ExclusiveSealed {
fn into_ptr<M: Mutability>(self: Box<Self>) -> CassExclusivePtr<Self, M> {
CassExclusivePtr::new(self)
}
Expand Down Expand Up @@ -325,7 +331,7 @@ pub trait BoxFFI: Sized {
/// The data should be allocated via [`Arc::new`], and then returned to the user as a pointer.
/// The user is responsible for freeing the memory associated
/// with the pointer using corresponding driver's API function.
pub trait ArcFFI: Sized {
pub trait ArcFFI: Sized + own_sealed::SharedSealed {
fn as_ptr(self: &Arc<Self>) -> CassSharedPtr<Self> {
CassSharedPtr::from_ref(self)
}
Expand Down Expand Up @@ -360,7 +366,7 @@ pub trait ArcFFI: Sized {
/// For example: lifetime of CassRow is bound by the lifetime of CassResult.
/// There is no API function that frees the CassRow. It should be automatically
/// freed when user calls cass_result_free.
pub trait RefFFI: Sized {
pub trait RefFFI: Sized + own_sealed::BorrowedSealed {
fn as_ptr(&self) -> CassBorrowedPtr<Self> {
CassBorrowedPtr::from_ref(self)
}
Expand All @@ -374,3 +380,19 @@ pub trait RefFFI: Sized {
ptr.is_null()
}
}

pub trait FFI {
type Ownerhsip;
}

pub struct OwnershipExclusive;
impl<T> own_sealed::ExclusiveSealed for T where T: FFI<Ownerhsip = OwnershipExclusive> {}
impl<T> BoxFFI for T where T: FFI<Ownerhsip = OwnershipExclusive> {}

pub struct OwnershipShared;
impl<T> own_sealed::SharedSealed for T where T: FFI<Ownerhsip = OwnershipShared> {}
impl<T> ArcFFI for T where T: FFI<Ownerhsip = OwnershipShared> {}

pub struct OwnershipBorrowed;
impl<T> own_sealed::BorrowedSealed for T where T: FFI<Ownerhsip = OwnershipBorrowed> {}
impl<T> RefFFI for T where T: FFI<Ownerhsip = OwnershipBorrowed> {}
9 changes: 7 additions & 2 deletions scylla-rust-wrapper/src/batch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::argconv::{ArcFFI, BoxFFI, CassExclusiveConstPtr, CassExclusiveMutPtr, CassSharedPtr};
use crate::argconv::{
ArcFFI, BoxFFI, CassExclusiveConstPtr, CassExclusiveMutPtr, CassSharedPtr, OwnershipExclusive,
FFI,
};
use crate::cass_error::CassError;
use crate::cass_types::CassConsistency;
use crate::cass_types::{make_batch_type, CassBatchType};
Expand All @@ -19,7 +22,9 @@ pub struct CassBatch {
pub(crate) exec_profile: Option<PerStatementExecProfile>,
}

impl BoxFFI for CassBatch {}
impl FFI for CassBatch {
type Ownerhsip = OwnershipExclusive;
}

#[derive(Clone)]
pub struct CassBatchState {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/cass_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ pub enum CassDataTypeInner {
Custom(String),
}

impl ArcFFI for CassDataType {}
impl FFI for CassDataType {
type Ownerhsip = OwnershipShared;
}

impl CassDataTypeInner {
/// Checks for equality during typechecks.
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ impl CassCluster {
}
}

impl BoxFFI for CassCluster {}
impl FFI for CassCluster {
type Ownerhsip = OwnershipExclusive;
}

pub struct CassCustomPayload;

Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ pub struct CassCollection {
pub items: Vec<CassCqlValue>,
}

impl BoxFFI for CassCollection {}
impl FFI for CassCollection {
type Ownerhsip = OwnershipExclusive;
}

impl CassCollection {
fn typecheck_on_append(&self, value: &Option<CassCqlValue>) -> CassError {
Expand Down
9 changes: 7 additions & 2 deletions scylla-rust-wrapper/src/exec_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use scylla::retry_policy::RetryPolicy;
use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy;
use scylla::statement::Consistency;

use crate::argconv::{ptr_to_cstr_n, strlen, ArcFFI, BoxFFI, CassExclusiveMutPtr, CassSharedPtr};
use crate::argconv::{
ptr_to_cstr_n, strlen, ArcFFI, BoxFFI, CassExclusiveMutPtr, CassSharedPtr, OwnershipExclusive,
FFI,
};
use crate::batch::CassBatch;
use crate::cass_error::CassError;
use crate::cass_types::CassConsistency;
Expand All @@ -37,7 +40,9 @@ pub struct CassExecProfile {
load_balancing_config: LoadBalancingConfig,
}

impl BoxFFI for CassExecProfile {}
impl FFI for CassExecProfile {
type Ownerhsip = OwnershipExclusive;
}

impl CassExecProfile {
fn new() -> Self {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ pub struct CassFuture {
wait_for_value: Condvar,
}

impl ArcFFI for CassFuture {}
impl FFI for CassFuture {
type Ownerhsip = OwnershipShared;
}

/// An error that can appear during `cass_future_wait_timed`.
enum FutureError {
Expand Down
8 changes: 6 additions & 2 deletions scylla-rust-wrapper/src/logging.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::argconv::{arr_to_cstr, ptr_to_cstr, str_to_arr, CassBorrowedPtr, RefFFI};
use crate::argconv::{
arr_to_cstr, ptr_to_cstr, str_to_arr, CassBorrowedPtr, OwnershipBorrowed, RefFFI, FFI,
};
use crate::cass_log_types::{CassLogLevel, CassLogMessage};
use crate::types::size_t;
use crate::LOGGER;
Expand All @@ -14,7 +16,9 @@ use tracing_subscriber::layer::Context;
use tracing_subscriber::prelude::*;
use tracing_subscriber::Layer;

impl RefFFI for CassLogMessage {}
impl FFI for CassLogMessage {
type Ownerhsip = OwnershipBorrowed;
}

pub type CassLogCallback =
Option<unsafe extern "C" fn(message: CassBorrowedPtr<CassLogMessage>, data: *mut c_void)>;
Expand Down
20 changes: 15 additions & 5 deletions scylla-rust-wrapper/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ pub struct CassSchemaMeta {
pub keyspaces: HashMap<String, CassKeyspaceMeta>,
}

impl BoxFFI for CassSchemaMeta {}
impl FFI for CassSchemaMeta {
type Ownerhsip = OwnershipExclusive;
}

pub struct CassKeyspaceMeta {
pub name: String,
Expand All @@ -25,7 +27,9 @@ pub struct CassKeyspaceMeta {
}

// Owned by CassSchemaMeta
impl RefFFI for CassKeyspaceMeta {}
impl FFI for CassKeyspaceMeta {
type Ownerhsip = OwnershipBorrowed;
}

pub struct CassTableMeta {
pub name: String,
Expand All @@ -38,7 +42,9 @@ pub struct CassTableMeta {
// Either:
// - owned by CassMaterializedViewMeta - won't be given to user
// - Owned by CassKeyspaceMeta (in Arc), referenced (Weak) by CassMaterializedViewMeta
impl RefFFI for CassTableMeta {}
impl FFI for CassTableMeta {
type Ownerhsip = OwnershipBorrowed;
}

pub struct CassMaterializedViewMeta {
pub name: String,
Expand All @@ -47,7 +53,9 @@ pub struct CassMaterializedViewMeta {
}

// Shared ownership by CassKeyspaceMeta and CassTableMeta
impl RefFFI for CassMaterializedViewMeta {}
impl FFI for CassMaterializedViewMeta {
type Ownerhsip = OwnershipBorrowed;
}

pub struct CassColumnMeta {
pub name: String,
Expand All @@ -56,7 +64,9 @@ pub struct CassColumnMeta {
}

// Owned by CassTableMeta
impl RefFFI for CassColumnMeta {}
impl FFI for CassColumnMeta {
type Ownerhsip = OwnershipBorrowed;
}

pub unsafe fn create_table_metadata(
keyspace_name: &str,
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/prepared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ impl CassPrepared {
}
}

impl ArcFFI for CassPrepared {}
impl FFI for CassPrepared {
type Ownerhsip = OwnershipShared;
}

#[no_mangle]
pub unsafe extern "C" fn cass_prepared_free(prepared_raw: CassSharedPtr<CassPrepared>) {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/query_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub enum CassErrorResult {
Deserialization(#[from] DeserializationError),
}

impl ArcFFI for CassErrorResult {}
impl FFI for CassErrorResult {
type Ownerhsip = OwnershipShared;
}

impl From<Consistency> for CassConsistency {
fn from(c: Consistency) -> CassConsistency {
Expand Down
16 changes: 12 additions & 4 deletions scylla-rust-wrapper/src/query_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ impl CassResult {
}
}

impl ArcFFI for CassResult {}
impl FFI for CassResult {
type Ownerhsip = OwnershipShared;
}

#[derive(Debug)]
pub struct CassResultMetadata {
Expand Down Expand Up @@ -149,7 +151,9 @@ pub struct CassRow {
pub result_metadata: Arc<CassResultMetadata>,
}

impl RefFFI for CassRow {}
impl FFI for CassRow {
type Ownerhsip = OwnershipBorrowed;
}

pub fn create_cass_rows_from_rows(
rows: Vec<Row>,
Expand Down Expand Up @@ -185,7 +189,9 @@ pub struct CassValue {
pub value_type: Arc<CassDataType>,
}

impl RefFFI for CassValue {}
impl FFI for CassValue {
type Ownerhsip = OwnershipBorrowed;
}

fn create_cass_row_columns(row: Row, metadata: &Arc<CassResultMetadata>) -> Vec<CassValue> {
row.columns
Expand Down Expand Up @@ -367,7 +373,9 @@ pub enum CassIterator {
CassViewMetaIterator(CassViewMetaIterator),
}

impl BoxFFI for CassIterator {}
impl FFI for CassIterator {
type Ownerhsip = OwnershipExclusive;
}

#[no_mangle]
pub unsafe extern "C" fn cass_iterator_free(iterator: CassExclusiveMutPtr<CassIterator>) {
Expand Down
6 changes: 4 additions & 2 deletions scylla-rust-wrapper/src/retry_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use scylla::retry_policy::{DefaultRetryPolicy, FallthroughRetryPolicy};
use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
use std::sync::Arc;

use crate::argconv::{ArcFFI, CassSharedPtr};
use crate::argconv::{ArcFFI, CassSharedPtr, OwnershipShared, FFI};

pub enum RetryPolicy {
DefaultRetryPolicy(Arc<DefaultRetryPolicy>),
Expand All @@ -12,7 +12,9 @@ pub enum RetryPolicy {

pub type CassRetryPolicy = RetryPolicy;

impl ArcFFI for CassRetryPolicy {}
impl FFI for CassRetryPolicy {
type Ownerhsip = OwnershipShared;
}

#[no_mangle]
pub extern "C" fn cass_retry_policy_default_new() -> CassSharedPtr<CassRetryPolicy> {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ impl CassSessionInner {

pub type CassSession = RwLock<Option<CassSessionInner>>;

impl ArcFFI for CassSession {}
impl FFI for CassSession {
type Ownerhsip = OwnershipShared;
}

#[no_mangle]
pub unsafe extern "C" fn cass_session_new() -> CassSharedPtr<CassSession> {
Expand Down
6 changes: 5 additions & 1 deletion scylla-rust-wrapper/src/ssl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::argconv::ArcFFI;
use crate::argconv::CassSharedPtr;
use crate::argconv::OwnershipShared;
use crate::argconv::FFI;
use crate::cass_error::CassError;
use crate::types::size_t;
use libc::{c_int, strlen};
Expand All @@ -20,7 +22,9 @@ pub struct CassSsl {
pub(crate) trusted_store: *mut X509_STORE,
}

impl ArcFFI for CassSsl {}
impl FFI for CassSsl {
type Ownerhsip = OwnershipShared;
}

pub const CASS_SSL_VERIFY_NONE: i32 = 0x00;
pub const CASS_SSL_VERIFY_PEER_CERT: i32 = 0x01;
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ pub struct CassStatement {
pub(crate) exec_profile: Option<PerStatementExecProfile>,
}

impl BoxFFI for CassStatement {}
impl FFI for CassStatement {
type Ownerhsip = OwnershipExclusive;
}

impl CassStatement {
fn bind_cql_value(&mut self, index: usize, value: Option<CassCqlValue>) -> CassError {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub struct CassTuple {
pub items: Vec<Option<CassCqlValue>>,
}

impl BoxFFI for CassTuple {}
impl FFI for CassTuple {
type Ownerhsip = OwnershipExclusive;
}

impl CassTuple {
fn get_types(&self) -> Option<&Vec<Arc<CassDataType>>> {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/user_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ pub struct CassUserType {
pub field_values: Vec<Option<CassCqlValue>>,
}

impl BoxFFI for CassUserType {}
impl FFI for CassUserType {
type Ownerhsip = OwnershipExclusive;
}

impl CassUserType {
fn set_field_by_index(&mut self, index: usize, value: Option<CassCqlValue>) -> CassError {
Expand Down
4 changes: 3 additions & 1 deletion scylla-rust-wrapper/src/uuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ pub struct CassUuidGen {
pub last_timestamp: AtomicU64,
}

impl BoxFFI for CassUuidGen {}
impl FFI for CassUuidGen {
type Ownerhsip = OwnershipExclusive;
}

// Implementation directly ported from Cpp Driver implementation:

Expand Down

0 comments on commit e8d2d93

Please sign in to comment.