Skip to content

Commit

Permalink
[feature] hyperledger-iroha#2488: Add support for trait impls in `ffi…
Browse files Browse the repository at this point in the history
…_export`

Signed-off-by: Shanin Roman <[email protected]>
  • Loading branch information
Erigara authored Aug 15, 2022
1 parent 2b2164b commit 52adcbf
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 233 deletions.
13 changes: 5 additions & 8 deletions data_model/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ ffi_item! {
IntoSchema,
)]
#[id(type = "<Account as Identifiable>::Id")]
#[allow(clippy::multiple_inherent_impl)]
#[display(fmt = "[{id}]")]
pub struct NewAccount {
/// Identification
Expand Down Expand Up @@ -184,6 +183,11 @@ impl HasMetadata for NewAccount {
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewAccount {
fn new(
id: <Account as Identifiable>::Id,
Expand All @@ -200,14 +204,7 @@ impl NewAccount {
pub(crate) fn id(&self) -> &<Account as Identifiable>::Id {
&self.id
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewAccount {
/// Add [`Metadata`] to the account replacing previously defined
#[must_use]
pub fn with_metadata(mut self, metadata: Metadata) -> Self {
Expand Down
13 changes: 5 additions & 8 deletions data_model/src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ ffi_item! {
)]
#[id(type = "<AssetDefinition as Identifiable>::Id")]
#[display(fmt = "{id} {mintable}{value_type}")]
#[allow(clippy::multiple_inherent_impl)]
pub struct NewAssetDefinition {
id: <AssetDefinition as Identifiable>::Id,
value_type: AssetValueType,
Expand Down Expand Up @@ -457,6 +456,11 @@ impl HasMetadata for NewAssetDefinition {
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewAssetDefinition {
/// Create a [`NewAssetDefinition`], reserved for internal use.
fn new(id: <AssetDefinition as Identifiable>::Id, value_type: AssetValueType) -> Self {
Expand All @@ -473,14 +477,7 @@ impl NewAssetDefinition {
pub(crate) fn id(&self) -> &<AssetDefinition as Identifiable>::Id {
&self.id
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewAssetDefinition {
/// Set mintability to [`Mintable::Once`]
#[inline]
#[must_use]
Expand Down
13 changes: 5 additions & 8 deletions data_model/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ ffi_item! {
IntoSchema,
)]
#[id(type = "<Domain as Identifiable>::Id")]
#[allow(clippy::multiple_inherent_impl)]
#[display(fmt = "[{id}]")]
pub struct NewDomain {
/// The identification associated with the domain builder.
Expand Down Expand Up @@ -125,6 +124,11 @@ impl HasMetadata for NewDomain {
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewDomain {
/// Create a [`NewDomain`], reserved for internal use.
#[must_use]
Expand All @@ -140,14 +144,7 @@ impl NewDomain {
pub(crate) fn id(&self) -> &<Domain as Identifiable>::Id {
&self.id
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewDomain {
/// Add [`logo`](IpfsPath) to the domain replacing previously defined value
#[must_use]
pub fn with_logo(mut self, logo: IpfsPath) -> Self {
Expand Down
2 changes: 0 additions & 2 deletions data_model/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,7 @@ impl Metadata {
pub fn iter(&self) -> impl ExactSizeIterator<Item = (&Name, &Value)> {
self.map.iter()
}
}

impl Metadata {
/// Get the `Some(&Value)` associated to `key`. Return `None` if not found.
#[inline]
pub fn get<K: Ord + ?Sized>(&self, key: &K) -> Option<&Value>
Expand Down
75 changes: 5 additions & 70 deletions data_model/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ impl AsRef<str> for Name {
}
}

#[cfg_attr(
all(feature = "ffi_export", not(feature = "ffi_import")),
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl FromStr for Name {
type Err = ParseError;

Expand All @@ -96,48 +101,6 @@ impl FromStr for Name {
}
}

/// FFI function equivalent of [`Name::from_str`]
///
/// # Safety
///
/// All of the given pointers must be valid
#[no_mangle]
#[allow(non_snake_case, unsafe_code)]
#[cfg(all(feature = "ffi_export", not(feature = "ffi_import")))]
pub unsafe extern "C" fn Name__from_str<'itm>(
candidate: <&'itm str as iroha_ffi::TryFromReprC<'itm>>::Source,
out_ptr: <<Name as iroha_ffi::IntoFfi>::Target as iroha_ffi::Output>::OutPtr,
) -> iroha_ffi::FfiReturn {
let res = std::panic::catch_unwind(|| {
// False positive - doesn't compile otherwise
#[allow(clippy::let_unit_value)]
let fn_body = || {
let mut store = Default::default();
let candidate: &str = iroha_ffi::TryFromReprC::try_from_repr_c(candidate, &mut store)?;
let method_res = iroha_ffi::IntoFfi::into_ffi(
// TODO: Implement error handling (https://github.com/hyperledger/iroha/issues/2252)
Name::from_str(candidate).map_err(|_e| iroha_ffi::FfiReturn::ExecutionFail)?,
);
iroha_ffi::OutPtrOf::write(out_ptr, method_res)?;
Ok(())
};

if let Err(err) = fn_body() {
return err;
}

iroha_ffi::FfiReturn::Ok
});

match res {
Ok(res) => res,
Err(_) => {
// TODO: Implement error handling (https://github.com/hyperledger/iroha/issues/2252)
iroha_ffi::FfiReturn::UnrecoverableError
}
}
}

impl<'de> Deserialize<'de> for Name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down Expand Up @@ -194,32 +157,4 @@ mod tests {
assert!(name.is_err());
}
}

#[test]
#[allow(unsafe_code)]
#[cfg(all(feature = "ffi_export", not(feature = "ffi_import")))]
fn ffi_name_from_str() -> Result<(), ParseError> {
use iroha_ffi::Handle;
let candidate = "Name";

unsafe {
let mut name = core::mem::MaybeUninit::new(core::ptr::null_mut());

assert_eq!(
iroha_ffi::FfiReturn::Ok,
Name__from_str(candidate.into_ffi(), name.as_mut_ptr())
);

let name = name.assume_init();
assert_ne!(core::ptr::null_mut(), name);
assert_eq!(Name::from_str(candidate)?, *name);

assert_eq!(
iroha_ffi::FfiReturn::Ok,
crate::ffi::__drop(Name::ID, name.cast())
);
}

Ok(())
}
}
19 changes: 8 additions & 11 deletions data_model/src/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ impl Registered for Role {
TryFromReprC,
IntoSchema,
)]
#[allow(clippy::multiple_inherent_impl)]
#[id(type = "<Role as Identifiable>::Id")]
pub struct NewRole {
inner: Role,
Expand All @@ -144,16 +143,6 @@ impl crate::Registrable for NewRole {
iroha_ffi::ffi_export
)]
#[cfg_attr(feature = "ffi_import", iroha_ffi::ffi_import)]
impl NewRole {
/// Add permission to the [`Role`]
#[must_use]
#[inline]
pub fn add_permission(mut self, perm: impl Into<PermissionToken>) -> Self {
self.inner.permissions.insert(perm.into());
self
}
}

impl NewRole {
/// Constructor
#[must_use]
Expand All @@ -172,6 +161,14 @@ impl NewRole {
pub(crate) fn id(&self) -> &<Role as Identifiable>::Id {
&self.inner.id
}

/// Add permission to the [`Role`]
#[must_use]
#[inline]
pub fn add_permission(mut self, perm: impl Into<PermissionToken>) -> Self {
self.inner.permissions.insert(perm.into());
self
}
}

/// The prelude re-exports most commonly used traits, structs and macros from this module.
Expand Down
Loading

0 comments on commit 52adcbf

Please sign in to comment.