Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Made ValueOrReceiptId::Value object consistent #208

Merged
merged 3 commits into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions workspaces/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ impl<'a> Function<'a> {
/// is most commonly constructed from [`Account::batch`] or [`Contract::batch`],
/// where `receiver_id` is specified in the `Account::batch` while `Contract::id()`
/// is used by default for `Contract::batch`.
///
/// [`Contract::batch`]: crate::Contract::batch
pub struct Transaction<'a> {
client: &'a Client,
signer: InMemorySigner,
Expand Down
68 changes: 54 additions & 14 deletions workspaces/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub type Result<T, E = crate::error::Error> = core::result::Result<T, E>;
/// Execution related info as a result of performing a successful transaction
/// execution on the network. This value can be converted into the returned
/// value of the transaction via [`ExecutionSuccess::json`] or [`ExecutionSuccess::borsh`]
pub type ExecutionSuccess = ExecutionResult<String>;
pub type ExecutionSuccess = ExecutionResult<Value>;

/// Execution related info as a result of performing a failed transaction
/// execution on the network. The related error message can be retrieved
Expand Down Expand Up @@ -198,7 +198,7 @@ impl ExecutionFinalResult {
match self.status {
FinalExecutionStatus::SuccessValue(value) => Ok(ExecutionResult {
total_gas_burnt: self.total_gas_burnt,
value: base64::encode(value),
value: Value::from_string(base64::encode(value)),
details: self.details,
}),
FinalExecutionStatus::Failure(tx_error) => Err(ExecutionResult {
Expand Down Expand Up @@ -293,25 +293,22 @@ impl ExecutionSuccess {
/// execution result of this call. This conversion can fail if the structure of
/// the internal state does not meet up with [`serde::de::DeserializeOwned`]'s
/// requirements.
pub fn json<U: serde::de::DeserializeOwned>(&self) -> Result<U> {
let buf = self.raw_bytes()?;
serde_json::from_slice(&buf).map_err(|e| ErrorKind::DataConversion.custom(e))
pub fn json<T: serde::de::DeserializeOwned>(&self) -> Result<T> {
self.value.json()
}

/// Deserialize an instance of type `T` from bytes sourced from the execution
/// result. This conversion can fail if the structure of the internal state does
/// not meet up with [`borsh::BorshDeserialize`]'s requirements.
pub fn borsh<U: borsh::BorshDeserialize>(&self) -> Result<U> {
let buf = self.raw_bytes()?;
borsh::BorshDeserialize::try_from_slice(&buf)
.map_err(|e| ErrorKind::DataConversion.custom(e))
pub fn borsh<T: borsh::BorshDeserialize>(&self) -> Result<T> {
self.value.borsh()
}

/// Grab the underlying raw bytes returned from calling into a contract's function.
/// If we want to deserialize these bytes into a rust datatype, use [`ExecutionResult::json`]
/// or [`ExecutionResult::borsh`] instead.
pub fn raw_bytes(&self) -> Result<Vec<u8>> {
base64::decode(&self.value).map_err(|e| ErrorKind::DataConversion.custom(e))
self.value.raw_bytes()
}
}

Expand Down Expand Up @@ -435,9 +432,9 @@ impl ExecutionOutcome {
/// particular outcome has failed or not.
pub fn into_result(self) -> Result<ValueOrReceiptId> {
match self.status {
ExecutionStatusView::SuccessValue(value) => {
Ok(ValueOrReceiptId::Value(base64::encode(value)))
}
ExecutionStatusView::SuccessValue(value) => Ok(ValueOrReceiptId::Value(
Value::from_string(base64::encode(value)),
)),
ExecutionStatusView::SuccessReceiptId(hash) => {
Ok(ValueOrReceiptId::ReceiptId(CryptoHash(hash.0)))
}
Expand All @@ -450,14 +447,57 @@ impl ExecutionOutcome {
}

/// Value or ReceiptId from a successful execution.
#[derive(Debug)]
pub enum ValueOrReceiptId {
/// The final action succeeded and returned some value or an empty vec encoded in base64.
Value(String),
Value(Value),
/// The final action of the receipt returned a promise or the signed transaction was converted
/// to a receipt. Contains the receipt_id of the generated receipt.
ReceiptId(CryptoHash),
}

/// Value type returned from an [`ExecutionOutcome`] or receipt result. This value
/// can be converted into the underlying Rust datatype, or directly grab the raw
/// bytes associated to the value.
#[derive(Debug)]
pub struct Value {
repr: String,
}

impl Value {
fn from_string(value: String) -> Self {
Self { repr: value }
}

/// Deserialize an instance of type `T` from bytes of JSON text sourced from the
/// execution result of this call. This conversion can fail if the structure of
/// the internal state does not meet up with [`serde::de::DeserializeOwned`]'s
/// requirements.
pub fn json<T: serde::de::DeserializeOwned>(&self) -> Result<T> {
let buf = self.raw_bytes()?;
serde_json::from_slice(&buf).map_err(|e| ErrorKind::DataConversion.custom(e))
}

/// Deserialize an instance of type `T` from bytes sourced from the execution
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved
/// result. This conversion can fail if the structure of the internal state does
/// not meet up with [`borsh::BorshDeserialize`]'s requirements.
pub fn borsh<T: borsh::BorshDeserialize>(&self) -> Result<T> {
let buf = self.raw_bytes()?;
borsh::BorshDeserialize::try_from_slice(&buf)
.map_err(|e| ErrorKind::DataConversion.custom(e))
}

/// Grab the underlying raw bytes returned from calling into a contract's function.
/// If we want to deserialize these bytes into a rust datatype, use [`json`]
/// or [`borsh`] instead.
///
/// [`json`]: Value::json
/// [`borsh`]: Value::borsh
pub fn raw_bytes(&self) -> Result<Vec<u8>> {
base64::decode(&self.repr).map_err(|e| ErrorKind::DataConversion.custom(e))
}
}

impl From<ExecutionOutcomeWithIdView> for ExecutionOutcome {
fn from(view: ExecutionOutcomeWithIdView) -> Self {
ExecutionOutcome {
Expand Down