use crate::types::object::Version;
use crate::types::Address;
use crate::types::ObjectDigest;
use crate::types::ObjectId;
use super::Command;
use super::TransactionExpiration;
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedTransaction")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Transaction {
#[cfg_attr(feature = "serde", serde(flatten))]
pub ptb: ProgrammableTransaction,
pub sender: Address,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub gas_payment: Option<GasPayment>,
pub expiration: TransactionExpiration,
}
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedProgrammableTransaction")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ProgrammableTransaction {
pub inputs: Vec<Input>,
pub commands: Vec<Command>,
}
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedGasPayment")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct GasPayment {
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
pub objects: Vec<ObjectReference>,
pub owner: Address,
#[cfg_attr(
feature = "serde",
serde(
with = "crate::_serde::OptionReadableDisplay",
default,
skip_serializing_if = "Option::is_none",
)
)]
#[cfg_attr(feature = "schemars", schemars(with = "Option<crate::_schemars::U64>"))]
pub price: Option<u64>,
#[cfg_attr(
feature = "serde",
serde(
with = "crate::_serde::OptionReadableDisplay",
default,
skip_serializing_if = "Option::is_none",
)
)]
#[cfg_attr(feature = "schemars", schemars(with = "Option<crate::_schemars::U64>"))]
pub budget: Option<u64>,
}
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedObjectReference")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ObjectReference {
pub object_id: ObjectId,
#[cfg_attr(
feature = "serde",
serde(
with = "crate::_serde::OptionReadableDisplay",
default,
skip_serializing_if = "Option::is_none",
)
)]
#[cfg_attr(feature = "schemars", schemars(with = "Option<crate::_schemars::U64>"))]
pub version: Option<Version>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub digest: Option<ObjectDigest>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedInputKind"),
serde(rename_all = "snake_case")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum InputKind {
Pure,
Shared,
Receiving,
ImmutableOrOwned,
Literal,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedInput")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Input {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub kind: Option<InputKind>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub value: Option<Value>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub object_id: Option<ObjectId>,
#[cfg_attr(
feature = "serde",
serde(
with = "crate::_serde::OptionReadableDisplay",
default,
skip_serializing_if = "Option::is_none",
alias = "initial_shared_version",
)
)]
#[cfg_attr(feature = "schemars", schemars(with = "Option<crate::_schemars::U64>"))]
pub version: Option<Version>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub digest: Option<ObjectDigest>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none",))]
pub mutable: Option<bool>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize),
serde(rename = "UnresolvedValue"),
serde(try_from = "serde_json::Value", into = "serde_json::Value")
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema), schemars(untagged))]
pub enum Value {
Null,
Bool(bool),
Number(u64),
String(String),
Array(Vec<Value>),
}
impl Input {
pub fn owned(object_id: ObjectId, version: u64, digest: ObjectDigest) -> Self {
Self {
kind: Some(InputKind::ImmutableOrOwned),
object_id: Some(object_id),
version: Some(version),
digest: Some(digest),
..Default::default()
}
}
pub fn immutable(object_id: ObjectId, version: u64, digest: ObjectDigest) -> Self {
Self {
kind: Some(InputKind::ImmutableOrOwned),
object_id: Some(object_id),
version: Some(version),
digest: Some(digest),
..Default::default()
}
}
pub fn receiving(object_id: ObjectId, version: u64, digest: ObjectDigest) -> Self {
Self {
kind: Some(InputKind::Receiving),
object_id: Some(object_id),
version: Some(version),
digest: Some(digest),
..Default::default()
}
}
pub fn shared(object_id: ObjectId, initial_shared_version: u64, mutable: bool) -> Self {
Self {
kind: Some(InputKind::Shared),
object_id: Some(object_id),
version: Some(initial_shared_version),
mutable: Some(mutable),
..Default::default()
}
}
pub fn by_id(object_id: ObjectId) -> Self {
Self {
object_id: Some(object_id),
..Default::default()
}
}
pub fn with_immutable_kind(&mut self) {
self.kind = Some(InputKind::ImmutableOrOwned);
}
pub fn with_owned_kind(&mut self) {
self.kind = Some(InputKind::ImmutableOrOwned);
}
pub fn with_receiving_kind(&mut self) {
self.kind = Some(InputKind::Receiving);
}
pub fn with_shared_kind(&mut self) {
self.kind = Some(InputKind::Shared);
}
pub fn with_version(&mut self, version: u64) {
self.version = Some(version);
}
pub fn with_digest(&mut self, digest: ObjectDigest) {
self.digest = Some(digest);
}
pub fn with_initial_shared_version(&mut self, initial: u64) {
self.version = Some(initial);
}
pub fn by_val(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(true);
}
pub fn by_ref(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(false);
}
pub fn by_mut(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(true);
}
}
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl TryFrom<serde_json::Value> for Value {
type Error = &'static str;
fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
let v = match value {
serde_json::Value::Null => Self::Null,
serde_json::Value::Bool(b) => Self::Bool(b),
serde_json::Value::Number(n) => {
Self::Number(n.as_u64().ok_or("expected unsigned integer")?)
}
serde_json::Value::String(s) => Self::String(s),
serde_json::Value::Array(a) => Self::Array(
a.into_iter()
.map(Self::try_from)
.collect::<Result<_, _>>()?,
),
serde_json::Value::Object(_) => return Err("objects are not supported"),
};
Ok(v)
}
}
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl From<Value> for serde_json::Value {
fn from(value: Value) -> Self {
match value {
Value::Null => Self::Null,
Value::Bool(b) => Self::Bool(b),
Value::Number(n) => Self::Number(n.into()),
Value::String(s) => Self::String(s),
Value::Array(a) => Self::Array(a.into_iter().map(Into::into).collect()),
}
}
}