use crate::admin::messages;
use crate::error::InvalidStateError;
use crate::protos::admin;
use crate::public_key::PublicKey;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ProposedNode {
node_id: String,
endpoints: Vec<String>,
public_key: Option<PublicKey>,
}
impl ProposedNode {
pub fn node_id(&self) -> &str {
&self.node_id
}
pub fn endpoints(&self) -> &[String] {
&self.endpoints
}
pub fn public_key(&self) -> &Option<PublicKey> {
&self.public_key
}
pub fn into_proto(self) -> admin::SplinterNode {
let mut proto = admin::SplinterNode::new();
proto.set_node_id(self.node_id);
proto.set_endpoints(self.endpoints.into());
if let Some(public_key) = self.public_key {
proto.set_public_key(public_key.into_bytes());
}
proto
}
pub fn from_proto(mut proto: admin::SplinterNode) -> Self {
let public_key = {
let public_key = proto.take_public_key();
if public_key.is_empty() {
None
} else {
Some(PublicKey::from_bytes(public_key))
}
};
Self {
node_id: proto.take_node_id(),
endpoints: proto.take_endpoints().into(),
public_key,
}
}
}
#[derive(Default, Clone)]
pub struct ProposedNodeBuilder {
node_id: Option<String>,
endpoints: Option<Vec<String>>,
public_key: Option<PublicKey>,
}
impl ProposedNodeBuilder {
pub fn new() -> Self {
ProposedNodeBuilder::default()
}
pub fn node_id(&self) -> Option<String> {
self.node_id.clone()
}
pub fn endpoints(&self) -> Option<Vec<String>> {
self.endpoints.clone()
}
pub fn public_key(&self) -> Option<PublicKey> {
self.public_key.clone()
}
pub fn with_node_id(mut self, node_id: &str) -> ProposedNodeBuilder {
self.node_id = Some(node_id.into());
self
}
pub fn with_endpoints(mut self, endpoints: &[String]) -> ProposedNodeBuilder {
self.endpoints = Some(endpoints.into());
self
}
pub fn with_public_key(mut self, public_key: &PublicKey) -> ProposedNodeBuilder {
self.public_key = Some(public_key.clone());
self
}
pub fn build(self) -> Result<ProposedNode, InvalidStateError> {
let node_id = self.node_id.ok_or_else(|| {
InvalidStateError::with_message("unable to build, missing field: `node_id`".to_string())
})?;
let endpoints = self.endpoints.ok_or_else(|| {
InvalidStateError::with_message(
"unable to build, missing field: `endpoints`".to_string(),
)
})?;
let node = ProposedNode {
node_id,
endpoints,
public_key: self.public_key,
};
Ok(node)
}
}
impl From<&messages::SplinterNode> for ProposedNode {
fn from(admin_node: &messages::SplinterNode) -> ProposedNode {
ProposedNode {
node_id: admin_node.node_id.to_string(),
endpoints: admin_node.endpoints.to_vec(),
public_key: admin_node.public_key.clone().map(PublicKey::from_bytes),
}
}
}