use std::sync::Arc;
use bytecheck::CheckBytes;
use dusk_wasmtime::{Engine, Module};
use piecrust_uplink::ContractId;
use rkyv::{Archive, Deserialize, Serialize};
use crate::error::Error;
pub struct ContractData<'a, A> {
pub(crate) contract_id: Option<ContractId>,
pub(crate) init_arg: Option<&'a A>,
pub(crate) owner: Option<Vec<u8>>,
}
impl<'a> ContractData<'a, ()> {
pub fn builder() -> ContractDataBuilder<'a, ()> {
ContractDataBuilder {
contract_id: None,
init_arg: None,
owner: None,
}
}
}
impl<'a, A> From<ContractDataBuilder<'a, A>> for ContractData<'a, A> {
fn from(builder: ContractDataBuilder<'a, A>) -> Self {
builder.build()
}
}
pub struct ContractDataBuilder<'a, A> {
contract_id: Option<ContractId>,
owner: Option<Vec<u8>>,
init_arg: Option<&'a A>,
}
impl<'a, A> ContractDataBuilder<'a, A> {
pub fn contract_id(mut self, id: ContractId) -> Self {
self.contract_id = Some(id);
self
}
pub fn init_arg<B>(self, arg: &B) -> ContractDataBuilder<B> {
ContractDataBuilder {
contract_id: self.contract_id,
owner: self.owner,
init_arg: Some(arg),
}
}
#[deprecated(note = "Use `init_arg` instead of `constructor_arg`")]
pub fn constructor_arg<B>(self, arg: &B) -> ContractDataBuilder<B> {
self.init_arg(arg)
}
pub fn owner(mut self, owner: impl Into<Vec<u8>>) -> Self {
self.owner = Some(owner.into());
self
}
pub fn build(self) -> ContractData<'a, A> {
ContractData {
contract_id: self.contract_id,
init_arg: self.init_arg,
owner: self.owner,
}
}
}
#[derive(Archive, Serialize, Deserialize, Debug, Clone)]
#[archive_attr(derive(CheckBytes))]
pub struct ContractMetadata {
pub contract_id: ContractId,
pub owner: Vec<u8>,
}
#[derive(Clone)]
pub struct WrappedContract {
serialized: Arc<Vec<u8>>,
}
impl WrappedContract {
pub fn new<B: AsRef<[u8]>, C: AsRef<[u8]>>(
engine: &Engine,
bytecode: B,
module: Option<C>,
) -> Result<Self, Error> {
let serialized = match module {
Some(obj) => obj.as_ref().to_vec(),
_ => {
let contract = Module::new(engine, bytecode.as_ref())?;
contract.serialize()?.to_vec()
}
};
Ok(WrappedContract {
serialized: Arc::new(serialized),
})
}
pub fn as_bytes(&self) -> &[u8] {
&self.serialized
}
}