use hedera_proto::services;
use prost::Message;
use time::OffsetDateTime;
use crate::protobuf::ToProtobuf;
use crate::{
AccountId,
FromProtobuf,
Key,
KeyList,
LedgerId,
ScheduleId,
TransactionId,
};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "ffi", derive(serde::Serialize, serde::Deserialize))]
pub struct ScheduleInfo {
pub schedule_id: ScheduleId,
pub creator_account_id: AccountId,
pub payer_account_id: Option<AccountId>,
pub signatories: KeyList,
pub admin_key: Option<Key>,
pub scheduled_transaction_id: TransactionId,
pub wait_for_expiry: bool,
pub schedule_memo: String,
#[cfg_attr(
feature = "ffi",
serde(with = "serde_with::As::<Option<serde_with::TimestampNanoSeconds>>")
)]
pub expiration_time: Option<OffsetDateTime>,
#[cfg_attr(
feature = "ffi",
serde(with = "serde_with::As::<Option<serde_with::TimestampNanoSeconds>>")
)]
pub executed_at: Option<OffsetDateTime>,
#[cfg_attr(
feature = "ffi",
serde(with = "serde_with::As::<Option<serde_with::TimestampNanoSeconds>>")
)]
pub deleted_at: Option<OffsetDateTime>,
pub ledger_id: LedgerId,
}
impl ScheduleInfo {
pub fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
FromProtobuf::<services::ScheduleInfo>::from_bytes(bytes)
}
#[must_use]
pub fn to_bytes(&self) -> Vec<u8> {
services::ScheduleInfo {
schedule_id: Some(self.schedule_id.to_protobuf()),
expiration_time: self.expiration_time.to_protobuf(),
memo: self.schedule_memo.clone(),
admin_key: self.admin_key.to_protobuf(),
signers: (!self.signatories.is_empty())
.then(|| services::KeyList { keys: self.signatories.keys.to_protobuf() }),
creator_account_id: Some(self.creator_account_id.to_protobuf()),
payer_account_id: self.payer_account_id.to_protobuf(),
scheduled_transaction_id: Some(self.scheduled_transaction_id.to_protobuf()),
ledger_id: self.ledger_id.to_bytes(),
wait_for_expiry: self.wait_for_expiry,
scheduled_transaction_body: None,
data: None,
}
.encode_to_vec()
}
}
impl FromProtobuf<services::response::Response> for ScheduleInfo {
#[allow(deprecated)]
fn from_protobuf(pb: services::response::Response) -> crate::Result<Self>
where
Self: Sized,
{
let response = pb_getv!(pb, ScheduleGetInfo, services::response::Response);
let info = pb_getf!(response, schedule_info)?;
Self::from_protobuf(info)
}
}
impl FromProtobuf<services::ScheduleInfo> for ScheduleInfo {
fn from_protobuf(pb: services::ScheduleInfo) -> crate::Result<Self>
where
Self: Sized,
{
let schedule_id = pb_getf!(pb, schedule_id)?;
let creator_account_id = pb_getf!(pb, creator_account_id)?;
let payer_account_id = Option::from_protobuf(pb.payer_account_id)?;
let admin_key = Option::from_protobuf(pb.admin_key)?;
let ledger_id = LedgerId::from_bytes(pb.ledger_id);
let scheduled_transaction_id =
TransactionId::from_protobuf(pb_getf!(pb, scheduled_transaction_id)?)?;
let signatories = pb.signers.map(KeyList::from_protobuf).transpose()?.unwrap_or_default();
let (executed_at, deleted_at) = match pb.data {
Some(services::schedule_info::Data::DeletionTime(deleted)) => {
(None, Some(deleted.into()))
}
Some(services::schedule_info::Data::ExecutionTime(executed)) => {
(Some(executed.into()), None)
}
None => (None, None),
};
Ok(Self {
schedule_id: ScheduleId::from_protobuf(schedule_id)?,
executed_at,
deleted_at,
schedule_memo: pb.memo,
creator_account_id: AccountId::from_protobuf(creator_account_id)?,
payer_account_id,
expiration_time: pb.expiration_time.map(Into::into),
admin_key,
scheduled_transaction_id,
signatories,
wait_for_expiry: pb.wait_for_expiry,
ledger_id,
})
}
}