radix-common 1.3.1

A library of common types and functions shared by all layers of the Radix stack, from the Radix DLT project.
Documentation
use crate::prelude::*;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConversionError {
    NoDirectEquivalence,
    DecodeError(DecodeError),
    EncodeError(EncodeError),
}

type Result<T> = core::result::Result<T, ConversionError>;

pub fn scrypto_value_to_manifest_value(scrypto_value: ScryptoValue) -> Result<ManifestValue> {
    match scrypto_value {
        ScryptoValue::Bool { value } => Ok(ManifestValue::Bool { value }),
        ScryptoValue::I8 { value } => Ok(ManifestValue::I8 { value }),
        ScryptoValue::I16 { value } => Ok(ManifestValue::I16 { value }),
        ScryptoValue::I32 { value } => Ok(ManifestValue::I32 { value }),
        ScryptoValue::I64 { value } => Ok(ManifestValue::I64 { value }),
        ScryptoValue::I128 { value } => Ok(ManifestValue::I128 { value }),
        ScryptoValue::U8 { value } => Ok(ManifestValue::U8 { value }),
        ScryptoValue::U16 { value } => Ok(ManifestValue::U16 { value }),
        ScryptoValue::U32 { value } => Ok(ManifestValue::U32 { value }),
        ScryptoValue::U64 { value } => Ok(ManifestValue::U64 { value }),
        ScryptoValue::U128 { value } => Ok(ManifestValue::U128 { value }),
        ScryptoValue::String { value } => Ok(ManifestValue::String { value }),
        ScryptoValue::Enum {
            discriminator,
            fields,
        } => fields
            .into_iter()
            .map(scrypto_value_to_manifest_value)
            .collect::<Result<_>>()
            .map(|fields| ManifestValue::Enum {
                discriminator,
                fields,
            }),
        ScryptoValue::Array {
            element_value_kind,
            elements,
        } => {
            let element_value_kind = scrypto_value_kind_to_manifest_value_kind(element_value_kind)?;
            let elements = elements
                .into_iter()
                .map(scrypto_value_to_manifest_value)
                .collect::<Result<Vec<_>>>()?;
            Ok(ManifestValue::Array {
                element_value_kind,
                elements,
            })
        }
        ScryptoValue::Tuple { fields } => fields
            .into_iter()
            .map(scrypto_value_to_manifest_value)
            .collect::<Result<_>>()
            .map(|fields| ManifestValue::Tuple { fields }),
        ScryptoValue::Map {
            key_value_kind,
            value_value_kind,
            entries,
        } => {
            let key_value_kind = scrypto_value_kind_to_manifest_value_kind(key_value_kind)?;
            let value_value_kind = scrypto_value_kind_to_manifest_value_kind(value_value_kind)?;
            let entries = entries
                .into_iter()
                .map(|(key, value)| -> Result<(ManifestValue, ManifestValue)> {
                    let key = scrypto_value_to_manifest_value(key)?;
                    let value = scrypto_value_to_manifest_value(value)?;
                    Ok((key, value))
                })
                .collect::<Result<Vec<_>>>()?;
            Ok(ManifestValue::Map {
                key_value_kind,
                value_value_kind,
                entries,
            })
        }
        ScryptoValue::Custom {
            value: ScryptoCustomValue::Decimal(value),
        } => Ok(ManifestValue::Custom {
            value: ManifestCustomValue::Decimal(from_decimal(&value)),
        }),
        ScryptoValue::Custom {
            value: ScryptoCustomValue::PreciseDecimal(value),
        } => Ok(ManifestValue::Custom {
            value: ManifestCustomValue::PreciseDecimal(from_precise_decimal(&value)),
        }),
        ScryptoValue::Custom {
            value: ScryptoCustomValue::Reference(value),
        } => Ok(ManifestValue::Custom {
            value: ManifestCustomValue::Address(ManifestAddress::Static(value.0)),
        }),
        ScryptoValue::Custom {
            value: ScryptoCustomValue::NonFungibleLocalId(value),
        } => Ok(ManifestValue::Custom {
            value: ManifestCustomValue::NonFungibleLocalId(from_non_fungible_local_id(value)),
        }),
        ScryptoValue::Custom {
            value: ScryptoCustomValue::Own(..),
        } => Err(ConversionError::NoDirectEquivalence),
    }
}

pub fn scrypto_value_kind_to_manifest_value_kind(
    value_kind: ScryptoValueKind,
) -> Result<ManifestValueKind> {
    match value_kind {
        ScryptoValueKind::Bool => Ok(ManifestValueKind::Bool),
        ScryptoValueKind::I8 => Ok(ManifestValueKind::I8),
        ScryptoValueKind::I16 => Ok(ManifestValueKind::I16),
        ScryptoValueKind::I32 => Ok(ManifestValueKind::I32),
        ScryptoValueKind::I64 => Ok(ManifestValueKind::I64),
        ScryptoValueKind::I128 => Ok(ManifestValueKind::I128),
        ScryptoValueKind::U8 => Ok(ManifestValueKind::U8),
        ScryptoValueKind::U16 => Ok(ManifestValueKind::U16),
        ScryptoValueKind::U32 => Ok(ManifestValueKind::U32),
        ScryptoValueKind::U64 => Ok(ManifestValueKind::U64),
        ScryptoValueKind::U128 => Ok(ManifestValueKind::U128),
        ScryptoValueKind::String => Ok(ManifestValueKind::String),
        ScryptoValueKind::Enum => Ok(ManifestValueKind::Enum),
        ScryptoValueKind::Array => Ok(ManifestValueKind::Array),
        ScryptoValueKind::Tuple => Ok(ManifestValueKind::Tuple),
        ScryptoValueKind::Map => Ok(ManifestValueKind::Map),
        ScryptoValueKind::Custom(ScryptoCustomValueKind::Reference) => {
            Ok(ManifestValueKind::Custom(ManifestCustomValueKind::Address))
        }
        ScryptoValueKind::Custom(ScryptoCustomValueKind::Own) => {
            Err(ConversionError::NoDirectEquivalence)
        }
        ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal) => {
            Ok(ManifestValueKind::Custom(ManifestCustomValueKind::Decimal))
        }
        ScryptoValueKind::Custom(ScryptoCustomValueKind::PreciseDecimal) => Ok(
            ManifestValueKind::Custom(ManifestCustomValueKind::PreciseDecimal),
        ),
        ScryptoValueKind::Custom(ScryptoCustomValueKind::NonFungibleLocalId) => Ok(
            ManifestValueKind::Custom(ManifestCustomValueKind::NonFungibleLocalId),
        ),
    }
}

pub fn manifest_value_to_scrypto_value(manifest_value: ManifestValue) -> Result<ScryptoValue> {
    match manifest_value {
        ManifestValue::Bool { value } => Ok(ScryptoValue::Bool { value }),
        ManifestValue::I8 { value } => Ok(ScryptoValue::I8 { value }),
        ManifestValue::I16 { value } => Ok(ScryptoValue::I16 { value }),
        ManifestValue::I32 { value } => Ok(ScryptoValue::I32 { value }),
        ManifestValue::I64 { value } => Ok(ScryptoValue::I64 { value }),
        ManifestValue::I128 { value } => Ok(ScryptoValue::I128 { value }),
        ManifestValue::U8 { value } => Ok(ScryptoValue::U8 { value }),
        ManifestValue::U16 { value } => Ok(ScryptoValue::U16 { value }),
        ManifestValue::U32 { value } => Ok(ScryptoValue::U32 { value }),
        ManifestValue::U64 { value } => Ok(ScryptoValue::U64 { value }),
        ManifestValue::U128 { value } => Ok(ScryptoValue::U128 { value }),
        ManifestValue::String { value } => Ok(ScryptoValue::String { value }),
        ManifestValue::Enum {
            discriminator,
            fields,
        } => fields
            .into_iter()
            .map(manifest_value_to_scrypto_value)
            .collect::<Result<_>>()
            .map(|fields| ScryptoValue::Enum {
                discriminator,
                fields,
            }),
        ManifestValue::Array {
            element_value_kind,
            elements,
        } => {
            let element_value_kind = manifest_value_kind_to_scrypto_value_kind(element_value_kind)?;
            let elements = elements
                .into_iter()
                .map(manifest_value_to_scrypto_value)
                .collect::<Result<Vec<_>>>()?;
            Ok(ScryptoValue::Array {
                element_value_kind,
                elements,
            })
        }
        ManifestValue::Tuple { fields } => fields
            .into_iter()
            .map(manifest_value_to_scrypto_value)
            .collect::<Result<_>>()
            .map(|fields| ScryptoValue::Tuple { fields }),
        ManifestValue::Map {
            key_value_kind,
            value_value_kind,
            entries,
        } => {
            let key_value_kind = manifest_value_kind_to_scrypto_value_kind(key_value_kind)?;
            let value_value_kind = manifest_value_kind_to_scrypto_value_kind(value_value_kind)?;
            let entries = entries
                .into_iter()
                .map(|(key, value)| -> Result<(ScryptoValue, ScryptoValue)> {
                    let key = manifest_value_to_scrypto_value(key)?;
                    let value = manifest_value_to_scrypto_value(value)?;
                    Ok((key, value))
                })
                .collect::<Result<Vec<_>>>()?;
            Ok(ScryptoValue::Map {
                key_value_kind,
                value_value_kind,
                entries,
            })
        }
        ManifestValue::Custom {
            value: ManifestCustomValue::Address(ManifestAddress::Static(value)),
        } => Ok(ScryptoValue::Custom {
            value: ScryptoCustomValue::Reference(Reference(value)),
        }),
        ManifestValue::Custom {
            value: ManifestCustomValue::Decimal(value),
        } => Ok(ScryptoValue::Custom {
            value: ScryptoCustomValue::Decimal(to_decimal(&value)),
        }),
        ManifestValue::Custom {
            value: ManifestCustomValue::PreciseDecimal(value),
        } => Ok(ScryptoValue::Custom {
            value: ScryptoCustomValue::PreciseDecimal(to_precise_decimal(&value)),
        }),
        ManifestValue::Custom {
            value: ManifestCustomValue::NonFungibleLocalId(value),
        } => Ok(ScryptoValue::Custom {
            value: ScryptoCustomValue::NonFungibleLocalId(to_non_fungible_local_id(value)),
        }),
        ManifestValue::Custom {
            value:
                ManifestCustomValue::Bucket(..)
                | ManifestCustomValue::Proof(..)
                | ManifestCustomValue::AddressReservation(..)
                | ManifestCustomValue::Expression(..)
                | ManifestCustomValue::Blob(..)
                | ManifestCustomValue::Address(ManifestAddress::Named(..)),
        } => Err(ConversionError::NoDirectEquivalence),
    }
}

pub fn manifest_value_kind_to_scrypto_value_kind(
    value_kind: ManifestValueKind,
) -> Result<ScryptoValueKind> {
    match value_kind {
        ManifestValueKind::Bool => Ok(ScryptoValueKind::Bool),
        ManifestValueKind::I8 => Ok(ScryptoValueKind::I8),
        ManifestValueKind::I16 => Ok(ScryptoValueKind::I16),
        ManifestValueKind::I32 => Ok(ScryptoValueKind::I32),
        ManifestValueKind::I64 => Ok(ScryptoValueKind::I64),
        ManifestValueKind::I128 => Ok(ScryptoValueKind::I128),
        ManifestValueKind::U8 => Ok(ScryptoValueKind::U8),
        ManifestValueKind::U16 => Ok(ScryptoValueKind::U16),
        ManifestValueKind::U32 => Ok(ScryptoValueKind::U32),
        ManifestValueKind::U64 => Ok(ScryptoValueKind::U64),
        ManifestValueKind::U128 => Ok(ScryptoValueKind::U128),
        ManifestValueKind::String => Ok(ScryptoValueKind::String),
        ManifestValueKind::Enum => Ok(ScryptoValueKind::Enum),
        ManifestValueKind::Array => Ok(ScryptoValueKind::Array),
        ManifestValueKind::Tuple => Ok(ScryptoValueKind::Tuple),
        ManifestValueKind::Map => Ok(ScryptoValueKind::Map),
        ManifestValueKind::Custom(ManifestCustomValueKind::Address) => {
            Ok(ScryptoValueKind::Custom(ScryptoCustomValueKind::Reference))
        }
        ManifestValueKind::Custom(ManifestCustomValueKind::Decimal) => {
            Ok(ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal))
        }
        ManifestValueKind::Custom(ManifestCustomValueKind::PreciseDecimal) => Ok(
            ScryptoValueKind::Custom(ScryptoCustomValueKind::PreciseDecimal),
        ),
        ManifestValueKind::Custom(ManifestCustomValueKind::NonFungibleLocalId) => Ok(
            ScryptoValueKind::Custom(ScryptoCustomValueKind::NonFungibleLocalId),
        ),
        ManifestValueKind::Custom(
            ManifestCustomValueKind::Bucket
            | ManifestCustomValueKind::Proof
            | ManifestCustomValueKind::AddressReservation
            | ManifestCustomValueKind::Expression
            | ManifestCustomValueKind::Blob,
        ) => Err(ConversionError::NoDirectEquivalence),
    }
}