use super::Gas;
use crate::{
proto::{self, traits::ParseOptional},
AccountId, Coin, ErrorReport, Result,
};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, PartialOrd, Ord, Serialize)]
pub struct Fee {
pub amount: Vec<Coin>,
pub gas_limit: Gas,
pub payer: Option<AccountId>,
pub granter: Option<AccountId>,
}
impl Fee {
pub fn from_amount_and_gas(amount: Coin, gas_limit: impl Into<Gas>) -> Fee {
Fee {
amount: vec![amount],
gas_limit: gas_limit.into(),
payer: None,
granter: None,
}
}
}
impl TryFrom<proto::cosmos::tx::v1beta1::Fee> for Fee {
type Error = ErrorReport;
fn try_from(proto: proto::cosmos::tx::v1beta1::Fee) -> Result<Fee> {
Fee::try_from(&proto)
}
}
impl TryFrom<&proto::cosmos::tx::v1beta1::Fee> for Fee {
type Error = ErrorReport;
fn try_from(proto: &proto::cosmos::tx::v1beta1::Fee) -> Result<Fee> {
let amount = proto
.amount
.iter()
.map(TryFrom::try_from)
.collect::<Result<_, _>>()?;
Ok(Fee {
amount,
gas_limit: proto.gas_limit,
payer: proto.payer.parse_optional()?,
granter: proto.granter.parse_optional()?,
})
}
}
impl From<Fee> for proto::cosmos::tx::v1beta1::Fee {
fn from(fee: Fee) -> proto::cosmos::tx::v1beta1::Fee {
proto::cosmos::tx::v1beta1::Fee::from(&fee)
}
}
impl From<&Fee> for proto::cosmos::tx::v1beta1::Fee {
fn from(fee: &Fee) -> proto::cosmos::tx::v1beta1::Fee {
proto::cosmos::tx::v1beta1::Fee {
amount: fee.amount.iter().map(Into::into).collect(),
gas_limit: fee.gas_limit,
payer: fee
.payer
.as_ref()
.map(|id| id.to_string())
.unwrap_or_default(),
granter: fee
.granter
.as_ref()
.map(|id| id.to_string())
.unwrap_or_default(),
}
}
}