use crate::crypto::MuxedAccount;
use crate::error::{Error, Result};
use crate::operations::Operation;
use crate::xdr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendFootprintTtlOperation {
source_account: Option<MuxedAccount>,
extend_to: u32,
}
#[derive(Debug, Default)]
pub struct ExtendFootprintTtlOperationBuilder {
source_account: Option<MuxedAccount>,
extend_to: Option<u32>,
}
impl ExtendFootprintTtlOperation {
pub fn source_account(&self) -> &Option<MuxedAccount> {
&self.source_account
}
pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
&mut self.source_account
}
pub fn extend_to(&self) -> &u32 {
&self.extend_to
}
pub fn extend_to_mut(&mut self) -> &mut u32 {
&mut self.extend_to
}
pub fn to_xdr_operation_body(&self) -> Result<xdr::OperationBody> {
let inner = xdr::ExtendFootprintTtlOp {
ext: xdr::ExtensionPoint::V0,
extend_to: self.extend_to,
};
Ok(xdr::OperationBody::ExtendFootprintTtl(inner))
}
pub fn from_xdr_operation_body(
source_account: Option<MuxedAccount>,
x: &xdr::ExtendFootprintTtlOp,
) -> Result<ExtendFootprintTtlOperation> {
Ok(ExtendFootprintTtlOperation {
source_account,
extend_to: x.extend_to,
})
}
}
impl ExtendFootprintTtlOperationBuilder {
pub fn new() -> ExtendFootprintTtlOperationBuilder {
Default::default()
}
pub fn with_source_account<S>(mut self, source: S) -> ExtendFootprintTtlOperationBuilder
where
S: Into<MuxedAccount>,
{
self.source_account = Some(source.into());
self
}
pub fn with_extend_to(mut self, extend_to: u32) -> ExtendFootprintTtlOperationBuilder {
self.extend_to = Some(extend_to);
self
}
pub fn build(self) -> Result<Operation> {
let extend_to = self.extend_to.ok_or_else(|| {
Error::InvalidOperation("missing extend footprint ttl extend to".to_string())
})?;
if extend_to == 0 {
return Err(Error::InvalidOperation(
"extend footprint ttl extend_to must be greater than zero".to_string(),
));
}
Ok(Operation::ExtendFootprintTtl(ExtendFootprintTtlOperation {
source_account: self.source_account,
extend_to,
}))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::operations::tests::*;
use crate::operations::Operation;
use crate::xdr::{XDRDeserialize, XDRSerialize};
#[test]
fn test_extend_footprint_ttl_roundtrip() {
let op = ExtendFootprintTtlOperationBuilder::new()
.with_extend_to(12345)
.build()
.unwrap();
let encoded = op.xdr_base64().unwrap();
let decoded = Operation::from_xdr_base64(&encoded).unwrap();
assert_eq!(op, decoded);
assert!(decoded.source_account().is_none());
if let Operation::ExtendFootprintTtl(inner) = &decoded {
assert_eq!(*inner.extend_to(), 12345);
} else {
panic!("expected ExtendFootprintTtl operation");
}
}
#[test]
fn test_extend_footprint_ttl_with_source_account() {
let source = keypair0().public_key();
let op = ExtendFootprintTtlOperationBuilder::new()
.with_source_account(source)
.with_extend_to(999_999)
.build()
.unwrap();
let encoded = op.xdr_base64().unwrap();
let decoded = Operation::from_xdr_base64(&encoded).unwrap();
assert_eq!(op, decoded);
let inner = match &decoded {
Operation::ExtendFootprintTtl(op) => op,
_ => panic!("expected ExtendFootprintTtl operation"),
};
assert_eq!(*inner.extend_to(), 999_999);
assert!(inner.source_account().is_some());
}
}