-
Notifications
You must be signed in to change notification settings - Fork 4
Bindings source code conventions
When modifying bindings source code, please stick to the following conventions.
This:
pub struct ZcashDiversifier(Diversifier);
NOT this:
pub struct ZcashDiversifier {
inner: Diversifier,
}
When possible (no type names clashing):
use zcash_primitives::legacy::TransparentAddress;
// ...
pub struct ZcashTransparentAddress(TransparentAddress);
Instead of using longer paths like:
pub struct ZcashTransparentAddress(zcash_primitives::legacy::TransparentAddress);
Constructor named new
in librustzcash
- simply use a constructor
in .udl
.
Constructor with a name different than new
use Name={constructor name}
attribute in .udl
:
interface ZcashOrchardDiversifier {
[Name=from_bytes, Throws=ZcashError]
constructor(sequence<u8> bytes);
};
Unless it's the only constructor - then you may consider simply using new
in bindings Rust code and constructor
without Name
attribute in .udl
.
Constructors returning Option
- use Result
in bindings and ZcashError
in .udl
(chose or create a new error that seems the most appropriate) - uniffi-rs
does not support constructors returning optional types.
interface ZcashAccountPrivKey {
// ...
[Name=from_bytes, Throws=ZcashError]
constructor(sequence<u8> data);
We cannot return tuples in UDL
files. The workaround for representing this case
is to return a struct (dictionary in the UDL file) that will hold the same elements as the original tuple. As a convention, the name of the struct will be ZcashElement1Element2
. Lets see an example:
pub fn ovks_for_shielding(&self) -> (InternalOvk, ExternalOvk) {
//...
}
interface ZcashAccountPubKey {
// ...
ZcashInternalOvkExternalOvk ovks_for_shielding();sssss
// ...
};
dictionary ZcashInternalOvkExternalOvk {
ZcashInternalOvk internal_ovk;
ZcashExternalOvk external_ovk;
};
pub fn ovks_for_shielding(&self) -> ZcashInternalOvkExternalOvk {
//...
}
pub struct ZcashInternalOvkExternalOvk {
pub internal_ovk: Arc<ZcashInternalOvk>,
pub external_ovk: Arc<ZcashExternalOvk>,
}
impl From<(InternalOvk, ExternalOvk)> for ZcashInternalOvkExternalOvk {
fn from((internal_ovk, external_ovk): (InternalOvk, ExternalOvk)) -> Self {
ZcashInternalOvkExternalOvk {
internal_ovk: Arc::new(internal_ovk.into()),
external_ovk: Arc::new(external_ovk.into()),
}
}
}
Sometimes conversions among different objects are being done by implementing the From
trait. But this is not available for users of other programming languages. Whenever we want to explicitly expose this behaviour to the user, we will extend the API creeating methods like to_*()
which might make use of the From
traits under the hood.