Skip to content

Commit

Permalink
Add support for reading Message provider states (#29)
Browse files Browse the repository at this point in the history
Adds ability to read provider state data for a Message.
  • Loading branch information
alilleybrinker committed Feb 2, 2021
1 parent 9655b94 commit 3c26828
Show file tree
Hide file tree
Showing 4 changed files with 303 additions and 131 deletions.
112 changes: 111 additions & 1 deletion rust/pact_matching_ffi/src/models/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ pub use pact_matching::models::message::Message;
pub use pact_matching::models::provider_states::ProviderState;

/*===============================================================================================
* # FFI Functions
* # Message
*---------------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------------------------
* ## Constructors / Destructor
*/

/// Get a mutable pointer to a newly-created default message on the heap.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
Expand Down Expand Up @@ -88,6 +92,10 @@ pub unsafe extern "C" fn message_delete(message: *mut Message) -> c_int {
}
}

/*-----------------------------------------------------------------------------------------------
* ## Description
*/

/// Get a copy of the description.
/// The returned string must be deleted with `string_delete`.
///
Expand Down Expand Up @@ -153,6 +161,10 @@ pub unsafe extern "C" fn message_set_description(
}
}

/*-----------------------------------------------------------------------------------------------
* ## Provider States
*/

/// Get a copy of the provider state at the given index from this message.
/// A pointer to the structure will be written to `out_provider_state`,
/// only if no errors are encountered.
Expand Down Expand Up @@ -195,6 +207,104 @@ pub unsafe extern "C" fn message_get_provider_state(
}
}

/// Get an iterator over provider states.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
#[allow(clippy::or_fun_call)]
pub unsafe extern "C" fn message_get_provider_state_iter(
message: *mut Message,
) -> *mut ProviderStateIterator {
ffi! {
name: "message_get_provider_state_iter",
params: [message],
op: {
let message = as_mut!(message);

let iter = ProviderStateIterator {
current: 0,
message,
};

Ok(ptr::raw_to(iter))
},
fail: {
ptr::null_mut_to::<ProviderStateIterator>()
}
}
}

/// Get the next value from the iterator.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
#[allow(clippy::or_fun_call)]
pub unsafe extern "C" fn provider_state_iter_next(
iter: *mut ProviderStateIterator,
) -> *mut ProviderState {
ffi! {
name: "provider_state_iter_next",
params: [iter],
op: {
// Reconstitute the iterator.
let iter = as_mut!(iter);

// Reconstitute the message.
let message = as_mut!(iter.message);

// Get the current index from the iterator.
let index = iter.next();

// Get the value for the current index.
let provider_state = message.provider_states.get_mut(index).ok_or(anyhow::anyhow!("iter past the end of provider states"))?;

// Leak the value out to the C-side.
Ok(provider_state as *mut ProviderState)
},
fail: {
ptr::null_mut_to::<ProviderState>()
}
}
}

/// Delete the iterator.
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
#[allow(clippy::or_fun_call)]
pub unsafe extern "C" fn provider_state_iter_delete(
iter: *mut ProviderStateIterator,
) -> c_int {
ffi! {
name: "provider_state_iter_delete",
params: [iter],
op: {
ptr::drop_raw(iter);
Ok(EXIT_SUCCESS)
},
fail: {
EXIT_FAILURE
}
}
}

/// Iterator over individual provider states.
#[allow(missing_copy_implementations)]
#[allow(missing_debug_implementations)]
pub struct ProviderStateIterator {
current: usize,
message: *mut Message,
}

impl ProviderStateIterator {
fn next(&mut self) -> usize {
let idx = self.current;
self.current += 1;
idx
}
}

/*-----------------------------------------------------------------------------------------------
* ## Metadata
*/

/// Get a copy of the metadata value indexed by `key`.
/// The returned string must be deleted with `string_delete`.
///
Expand Down
129 changes: 0 additions & 129 deletions rust/pact_matching_ffi/src/models/metadata.rs

This file was deleted.

2 changes: 1 addition & 1 deletion rust/pact_matching_ffi/src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Represents messages in `pact_matching`.
pub mod message;
pub mod metadata;
pub mod pact_specification;
pub mod provider_state;
Loading

0 comments on commit 3c26828

Please sign in to comment.