-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rust): add FileCreate, FileUpdate, FileDelete, and FileAppend
- Loading branch information
Showing
9 changed files
with
419 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use async_trait::async_trait; | ||
use hedera_proto::services; | ||
use hedera_proto::services::file_service_client::FileServiceClient; | ||
use serde_with::skip_serializing_none; | ||
use tonic::transport::Channel; | ||
|
||
use crate::protobuf::ToProtobuf; | ||
use crate::transaction::{AnyTransactionData, ToTransactionDataProtobuf, TransactionExecute}; | ||
use crate::{AccountId, FileId, Transaction, TransactionId}; | ||
|
||
/// Append the given contents to the end of the specified file. | ||
/// | ||
pub type FileAppendTransaction = Transaction<FileAppendTransactionData>; | ||
|
||
#[skip_serializing_none] | ||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct FileAppendTransactionData { | ||
/// The file to which the bytes will be appended. | ||
file_id: Option<FileId>, | ||
|
||
/// The bytes that will be appended to the end of the specified file. | ||
contents: Option<Vec<u8>>, | ||
} | ||
|
||
impl FileAppendTransaction { | ||
/// Sets the file to which the bytes will be appended. | ||
pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self { | ||
self.body.data.file_id = Some(id.into()); | ||
self | ||
} | ||
|
||
/// Sets the bytes that will be appended to the end of the specified file. | ||
pub fn contents(&mut self, contents: Vec<u8>) -> &mut Self { | ||
self.body.data.contents = Some(contents); | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl TransactionExecute for FileAppendTransactionData { | ||
async fn execute( | ||
&self, | ||
channel: Channel, | ||
request: services::Transaction, | ||
) -> Result<tonic::Response<services::TransactionResponse>, tonic::Status> { | ||
FileServiceClient::new(channel).append_content(request).await | ||
} | ||
} | ||
|
||
impl ToTransactionDataProtobuf for FileAppendTransactionData { | ||
fn to_transaction_data_protobuf( | ||
&self, | ||
_node_account_id: AccountId, | ||
_transaction_id: &TransactionId, | ||
) -> services::transaction_body::Data { | ||
let file_id = self.file_id.as_ref().map(FileId::to_protobuf); | ||
|
||
services::transaction_body::Data::FileAppend(services::FileAppendTransactionBody { | ||
file_id, | ||
contents: self.contents.clone().unwrap_or_default(), | ||
}) | ||
} | ||
} | ||
|
||
impl From<FileAppendTransactionData> for AnyTransactionData { | ||
fn from(transaction: FileAppendTransactionData) -> Self { | ||
Self::FileAppend(transaction) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
use async_trait::async_trait; | ||
use hedera_proto::services; | ||
use hedera_proto::services::file_service_client::FileServiceClient; | ||
use itertools::Itertools; | ||
use serde_with::skip_serializing_none; | ||
use time::OffsetDateTime; | ||
use tonic::transport::Channel; | ||
|
||
use crate::protobuf::ToProtobuf; | ||
use crate::transaction::{AnyTransactionData, ToTransactionDataProtobuf, TransactionExecute}; | ||
use crate::{AccountId, Key, Transaction, TransactionId}; | ||
|
||
/// Create a new file, containing the given contents. | ||
pub type FileCreateTransaction = Transaction<FileCreateTransactionData>; | ||
|
||
#[skip_serializing_none] | ||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct FileCreateTransactionData { | ||
/// The memo associated with the file. | ||
#[serde(skip_serializing_if = "String::is_empty")] | ||
file_memo: String, | ||
|
||
/// All keys at the top level of a key list must sign to create or | ||
/// modify the file. Any one of the keys at the top level key list | ||
/// can sign to delete the file. | ||
keys: Option<Vec<Key>>, | ||
|
||
/// The bytes that are to be the contents of the file. | ||
contents: Option<Vec<u8>>, | ||
|
||
/// The time at which this file should expire. | ||
expires_at: Option<OffsetDateTime>, | ||
} | ||
|
||
impl FileCreateTransaction { | ||
/// Sets the memo associated with the file. | ||
pub fn file_memo(&mut self, memo: impl Into<String>) -> &mut Self { | ||
self.body.data.file_memo = memo.into(); | ||
self | ||
} | ||
|
||
/// Sets the bytes that are to be the contents of the file. | ||
pub fn contents(&mut self, contents: Vec<u8>) -> &mut Self { | ||
self.body.data.contents = Some(contents); | ||
self | ||
} | ||
|
||
/// Sets the keys for this file. | ||
/// | ||
/// All keys at the top level of a key list must sign to create or | ||
/// modify the file. Any one of the keys at the top level key list | ||
/// can sign to delete the file. | ||
/// | ||
pub fn keys<K: Into<Key>>(&mut self, keys: impl IntoIterator<Item = K>) -> &mut Self { | ||
self.body.data.keys = Some(keys.into_iter().map_into().collect()); | ||
self | ||
} | ||
|
||
/// Sets the time at which this file should expire. | ||
pub fn expires_at(&mut self, at: OffsetDateTime) -> &mut Self { | ||
self.body.data.expires_at = Some(at); | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl TransactionExecute for FileCreateTransactionData { | ||
async fn execute( | ||
&self, | ||
channel: Channel, | ||
request: services::Transaction, | ||
) -> Result<tonic::Response<services::TransactionResponse>, tonic::Status> { | ||
FileServiceClient::new(channel).create_file(request).await | ||
} | ||
} | ||
|
||
impl ToTransactionDataProtobuf for FileCreateTransactionData { | ||
fn to_transaction_data_protobuf( | ||
&self, | ||
_node_account_id: AccountId, | ||
_transaction_id: &TransactionId, | ||
) -> services::transaction_body::Data { | ||
let expiration_time = self.expires_at.as_ref().map(OffsetDateTime::to_protobuf); | ||
|
||
let keys = | ||
self.keys.as_deref().unwrap_or_default().iter().map(Key::to_protobuf).collect_vec(); | ||
|
||
let keys = services::KeyList { keys }; | ||
|
||
services::transaction_body::Data::FileCreate(services::FileCreateTransactionBody { | ||
expiration_time, | ||
keys: Some(keys), | ||
contents: self.contents.clone().unwrap_or_default(), | ||
shard_id: None, | ||
realm_id: None, | ||
new_realm_admin_key: None, | ||
memo: self.file_memo.clone(), | ||
}) | ||
} | ||
} | ||
|
||
impl From<FileCreateTransactionData> for AnyTransactionData { | ||
fn from(transaction: FileCreateTransactionData) -> Self { | ||
Self::FileCreate(transaction) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use async_trait::async_trait; | ||
use hedera_proto::services; | ||
use hedera_proto::services::file_service_client::FileServiceClient; | ||
use serde_with::skip_serializing_none; | ||
use tonic::transport::Channel; | ||
|
||
use crate::protobuf::ToProtobuf; | ||
use crate::transaction::{AnyTransactionData, ToTransactionDataProtobuf, TransactionExecute}; | ||
use crate::{AccountId, FileId, Transaction, TransactionId}; | ||
|
||
/// Delete the given file. | ||
/// | ||
/// After deletion, it will be marked as deleted and will have no contents. | ||
/// Information about it will continue to exist until it expires. | ||
/// | ||
pub type FileDeleteTransaction = Transaction<FileDeleteTransactionData>; | ||
|
||
#[skip_serializing_none] | ||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct FileDeleteTransactionData { | ||
/// The file to delete. It will be marked as deleted until it expires. | ||
/// Then it will disappear. | ||
file_id: Option<FileId>, | ||
} | ||
|
||
impl FileDeleteTransaction { | ||
/// Set the file to delete. | ||
pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self { | ||
self.body.data.file_id = Some(id.into()); | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl TransactionExecute for FileDeleteTransactionData { | ||
async fn execute( | ||
&self, | ||
channel: Channel, | ||
request: services::Transaction, | ||
) -> Result<tonic::Response<services::TransactionResponse>, tonic::Status> { | ||
FileServiceClient::new(channel).delete_file(request).await | ||
} | ||
} | ||
|
||
impl ToTransactionDataProtobuf for FileDeleteTransactionData { | ||
fn to_transaction_data_protobuf( | ||
&self, | ||
_node_account_id: AccountId, | ||
_transaction_id: &TransactionId, | ||
) -> services::transaction_body::Data { | ||
let file_id = self.file_id.as_ref().map(FileId::to_protobuf); | ||
|
||
services::transaction_body::Data::FileDelete(services::FileDeleteTransactionBody { | ||
file_id, | ||
}) | ||
} | ||
} | ||
|
||
impl From<FileDeleteTransactionData> for AnyTransactionData { | ||
fn from(transaction: FileDeleteTransactionData) -> Self { | ||
Self::FileDelete(transaction) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
use async_trait::async_trait; | ||
use hedera_proto::services; | ||
use hedera_proto::services::file_service_client::FileServiceClient; | ||
use itertools::Itertools; | ||
use serde_with::skip_serializing_none; | ||
use time::OffsetDateTime; | ||
use tonic::transport::Channel; | ||
|
||
use crate::protobuf::ToProtobuf; | ||
use crate::transaction::{AnyTransactionData, ToTransactionDataProtobuf, TransactionExecute}; | ||
use crate::{AccountId, FileId, Key, Transaction, TransactionId}; | ||
|
||
/// Modify the metadata and/or the contents of a file. | ||
/// | ||
/// If a field is not set in the transaction body, the | ||
/// corresponding file attribute will be unchanged. | ||
/// | ||
pub type FileUpdateTransaction = Transaction<FileUpdateTransactionData>; | ||
|
||
#[skip_serializing_none] | ||
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct FileUpdateTransactionData { | ||
/// The file ID which is being updated in this transaction. | ||
file_id: Option<FileId>, | ||
|
||
/// The memo associated with the file. | ||
file_memo: Option<String>, | ||
|
||
/// All keys at the top level of a key list must sign to create or | ||
/// modify the file. Any one of the keys at the top level key list | ||
/// can sign to delete the file. | ||
keys: Option<Vec<Key>>, | ||
|
||
/// The bytes that are to be the contents of the file. | ||
contents: Option<Vec<u8>>, | ||
|
||
/// The time at which this file should expire. | ||
expires_at: Option<OffsetDateTime>, | ||
} | ||
|
||
impl FileUpdateTransaction { | ||
/// Set the file ID which is being updated. | ||
pub fn file_id(&mut self, id: impl Into<FileId>) -> &mut Self { | ||
self.body.data.file_id = Some(id.into()); | ||
self | ||
} | ||
|
||
/// Sets the memo associated with the file. | ||
pub fn file_memo(&mut self, memo: impl Into<String>) -> &mut Self { | ||
self.body.data.file_memo = Some(memo.into()); | ||
self | ||
} | ||
|
||
/// Sets the bytes that are to be the contents of the file. | ||
pub fn contents(&mut self, contents: Vec<u8>) -> &mut Self { | ||
self.body.data.contents = Some(contents); | ||
self | ||
} | ||
|
||
/// Sets the keys for this file. | ||
/// | ||
/// All keys at the top level of a key list must sign to create or | ||
/// modify the file. Any one of the keys at the top level key list | ||
/// can sign to delete the file. | ||
/// | ||
pub fn keys<K: Into<Key>>(&mut self, keys: impl IntoIterator<Item = K>) -> &mut Self { | ||
self.body.data.keys = Some(keys.into_iter().map_into().collect()); | ||
self | ||
} | ||
|
||
/// Sets the time at which this file should expire. | ||
pub fn expires_at(&mut self, at: OffsetDateTime) -> &mut Self { | ||
self.body.data.expires_at = Some(at); | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl TransactionExecute for FileUpdateTransactionData { | ||
async fn execute( | ||
&self, | ||
channel: Channel, | ||
request: services::Transaction, | ||
) -> Result<tonic::Response<services::TransactionResponse>, tonic::Status> { | ||
FileServiceClient::new(channel).update_file(request).await | ||
} | ||
} | ||
|
||
impl ToTransactionDataProtobuf for FileUpdateTransactionData { | ||
fn to_transaction_data_protobuf( | ||
&self, | ||
_node_account_id: AccountId, | ||
_transaction_id: &TransactionId, | ||
) -> services::transaction_body::Data { | ||
let file_id = self.file_id.as_ref().map(FileId::to_protobuf); | ||
let expiration_time = self.expires_at.as_ref().map(OffsetDateTime::to_protobuf); | ||
|
||
let keys = | ||
self.keys.as_deref().unwrap_or_default().iter().map(Key::to_protobuf).collect_vec(); | ||
|
||
let keys = services::KeyList { keys }; | ||
|
||
services::transaction_body::Data::FileUpdate(services::FileUpdateTransactionBody { | ||
file_id, | ||
expiration_time, | ||
keys: Some(keys), | ||
contents: self.contents.clone().unwrap_or_default(), | ||
memo: self.file_memo.clone(), | ||
}) | ||
} | ||
} | ||
|
||
impl From<FileUpdateTransactionData> for AnyTransactionData { | ||
fn from(transaction: FileUpdateTransactionData) -> Self { | ||
Self::FileUpdate(transaction) | ||
} | ||
} |
Oops, something went wrong.