use crate::{DebugOption, Indexed};
use anyhow::{Context, Result};
use bc_envelope::prelude::*;
use super::ProtocolAddress;
#[derive(Clone, PartialEq)]
pub struct Address {
index: usize,
address: ProtocolAddress,
name: String,
purpose: Option<String>,
attachments: Attachments,
}
impl Indexed for Address {
fn index(&self) -> usize {
self.index
}
fn set_index(&mut self, index: usize) {
self.index = index;
}
}
impl std::fmt::Debug for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Address")
.field("address", &self.address)
.field("name", &self.name)
.field("purpose", &DebugOption(&self.purpose))
.field("attachments", &self.attachments)
.finish()
}
}
bc_envelope::impl_attachable!(Address);
impl Address {
pub fn new(address: ProtocolAddress) -> Self {
Self {
index: 0,
address,
name: String::default(),
purpose: None,
attachments: Attachments::new(),
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn purpose(&self) -> Option<&str> {
self.purpose.as_deref()
}
pub fn set_purpose(&mut self, purpose: String) {
self.purpose = Some(purpose);
}
pub fn as_string(&self) -> String {
self.address.as_string()
}
pub fn address(&self) -> &ProtocolAddress {
&self.address
}
pub fn address_mut(&mut self) -> &mut ProtocolAddress {
&mut self.address
}
pub fn set_name(&mut self, name: String) {
self.name = name;
}
pub fn set_address(&mut self, address: ProtocolAddress) {
self.address = address;
}
}
impl From<Address> for Envelope {
fn from(value: Address) -> Self {
let envelope = Envelope::new(value.index)
.add_type("Address")
.add_assertion("address", value.address)
.add_assertion("name", value.name)
.add_optional_assertion("purpose", value.purpose);
value.attachments.add_to_envelope(envelope)
}
}
impl TryFrom<Envelope> for Address {
type Error = anyhow::Error;
fn try_from(envelope: Envelope) -> Result<Self, Self::Error> {
envelope.check_type_envelope("Address").context("Address")?;
let index = envelope.extract_subject().context("index")?;
let address = envelope
.try_object_for_predicate("address")
.context("address")?;
let name = envelope.try_object_for_predicate("name").context("name")?;
let purpose = envelope
.try_optional_object_for_predicate("purpose")
.context("purpose")?;
let attachments = Attachments::try_from_envelope(&envelope).context("attachments")?;
Ok(Address {
index,
address,
name,
purpose,
attachments,
})
}
}
#[cfg(test)]
mod tests {
use bc_envelope::Attachments;
use crate::{ProtocolAddress, test_envelope_roundtrip};
use super::Address;
impl crate::RandomInstance for Address {
fn random() -> Self {
Self {
index: 0,
name: String::random(),
purpose: String::opt_random(),
address: ProtocolAddress::random(),
attachments: Attachments::random(),
}
}
}
test_envelope_roundtrip!(Address);
}