use hedera_proto::services;
use hedera_proto::services::file_service_client::FileServiceClient;
use time::{
Duration,
OffsetDateTime,
};
use tonic::transport::Channel;
use crate::protobuf::{
FromProtobuf,
ToProtobuf,
};
use crate::transaction::{
AnyTransactionData,
ChunkInfo,
ToSchedulableTransactionDataProtobuf,
ToTransactionDataProtobuf,
TransactionData,
TransactionExecute,
};
use crate::{
AccountId,
BoxGrpcFuture,
Error,
FileId,
Key,
KeyList,
LedgerId,
Transaction,
ValidateChecksums,
};
pub type FileUpdateTransaction = Transaction<FileUpdateTransactionData>;
#[derive(Debug, Clone, Default)]
pub struct FileUpdateTransactionData {
file_id: Option<FileId>,
file_memo: Option<String>,
keys: Option<KeyList>,
contents: Option<Vec<u8>>,
expiration_time: Option<OffsetDateTime>,
auto_renew_account_id: Option<AccountId>,
auto_renew_period: Option<Duration>,
}
impl FileUpdateTransaction {
#[must_use]
pub fn get_file_id(&self) -> Option<FileId> {
self.data().file_id
}
pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self {
self.data_mut().file_id = Some(id.into());
self
}
#[must_use]
pub fn get_file_memo(&self) -> Option<&str> {
self.data().file_memo.as_deref()
}
pub fn file_memo(&mut self, memo: impl Into<String>) -> &mut Self {
self.data_mut().file_memo = Some(memo.into());
self
}
#[must_use]
pub fn get_contents(&self) -> Option<&[u8]> {
self.data().contents.as_deref()
}
pub fn contents(&mut self, contents: Vec<u8>) -> &mut Self {
self.data_mut().contents = Some(contents);
self
}
#[must_use]
pub fn get_keys(&self) -> Option<&KeyList> {
self.data().keys.as_ref()
}
pub fn keys<K: Into<Key>>(&mut self, keys: impl IntoIterator<Item = K>) -> &mut Self {
self.data_mut().keys = Some(keys.into_iter().map(Into::into).collect());
self
}
#[must_use]
pub fn get_expiration_time(&self) -> Option<OffsetDateTime> {
self.data().expiration_time
}
pub fn expiration_time(&mut self, at: OffsetDateTime) -> &mut Self {
self.data_mut().expiration_time = Some(at);
self
}
#[must_use]
pub fn get_auto_renew_account_id(&self) -> Option<AccountId> {
self.data().auto_renew_account_id
}
pub fn auto_renew_account_id(&mut self, id: AccountId) -> &mut Self {
self.data_mut().auto_renew_account_id = Some(id);
self
}
#[must_use]
pub fn get_auto_renew_period(&self) -> Option<Duration> {
self.data().auto_renew_period
}
pub fn auto_renew_period(&mut self, duration: Duration) -> &mut Self {
self.data_mut().auto_renew_period = Some(duration);
self
}
}
impl TransactionData for FileUpdateTransactionData {}
impl TransactionExecute for FileUpdateTransactionData {
fn execute(
&self,
channel: Channel,
request: services::Transaction,
) -> BoxGrpcFuture<'_, services::TransactionResponse> {
Box::pin(async { FileServiceClient::new(channel).update_file(request).await })
}
}
impl ValidateChecksums for FileUpdateTransactionData {
fn validate_checksums(&self, ledger_id: &LedgerId) -> Result<(), Error> {
self.file_id.validate_checksums(ledger_id)
}
}
impl ToTransactionDataProtobuf for FileUpdateTransactionData {
fn to_transaction_data_protobuf(
&self,
chunk_info: &ChunkInfo,
) -> services::transaction_body::Data {
let _ = chunk_info.assert_single_transaction();
services::transaction_body::Data::FileUpdate(self.to_protobuf())
}
}
impl ToSchedulableTransactionDataProtobuf for FileUpdateTransactionData {
fn to_schedulable_transaction_data_protobuf(
&self,
) -> services::schedulable_transaction_body::Data {
services::schedulable_transaction_body::Data::FileUpdate(self.to_protobuf())
}
}
impl From<FileUpdateTransactionData> for AnyTransactionData {
fn from(transaction: FileUpdateTransactionData) -> Self {
Self::FileUpdate(transaction)
}
}
impl FromProtobuf<services::FileUpdateTransactionBody> for FileUpdateTransactionData {
fn from_protobuf(pb: services::FileUpdateTransactionBody) -> crate::Result<Self> {
Ok(Self {
file_id: Option::from_protobuf(pb.file_id)?,
file_memo: pb.memo,
keys: Option::from_protobuf(pb.keys)?,
contents: Some(pb.contents),
expiration_time: pb.expiration_time.map(Into::into),
auto_renew_account_id: None,
auto_renew_period: None,
})
}
}
impl ToProtobuf for FileUpdateTransactionData {
type Protobuf = services::FileUpdateTransactionBody;
fn to_protobuf(&self) -> Self::Protobuf {
services::FileUpdateTransactionBody {
file_id: self.file_id.to_protobuf(),
expiration_time: self.expiration_time.to_protobuf(),
keys: self.keys.to_protobuf(),
contents: self.contents.clone().unwrap_or_default(),
memo: self.file_memo.clone(),
}
}
}