use std::cmp::PartialEq;
use std::hash::{Hash, Hasher};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use crate::message::NodeProfileMessage;
use crate::object::{Object, ObjectCode};
use crate::protocol::Message;
pub struct RemoteNode {
addr: SocketAddr,
objects: Vec<Object>,
}
impl RemoteNode {
pub fn new() -> RemoteNode {
RemoteNode {
addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0),
objects: Vec::new(),
}
}
pub fn from_message(msg: &Message) -> RemoteNode {
let mut node = RemoteNode {
addr: msg.from(),
objects: Vec::new(),
};
node.parse(msg);
node
}
pub fn addr(&self) -> SocketAddr {
self.addr
}
pub fn set_addr(&mut self, addr: SocketAddr) {
self.addr = addr
}
pub fn add_object(&mut self, obj: Object) -> bool {
self.objects.push(obj);
true
}
pub fn objects(&self) -> &Vec<Object> {
return &self.objects;
}
pub fn objects_mut(&mut self) -> &mut Vec<Object> {
return &mut self.objects;
}
pub fn find_object(&self, code: ObjectCode) -> Option<&Object> {
for n in 0..self.objects.len() {
if self.objects[n].code() == code {
return Some(&self.objects[n]);
}
}
None
}
fn parse(&mut self, msg: &Message) -> bool {
if !msg.is_node_profile_message() {
return false;
}
let mut profile_msg = NodeProfileMessage::from_message(msg);
if !profile_msg.parse() {
return false;
}
for object_code in profile_msg.object_codes().iter() {
self.add_object(Object::from_code(*object_code));
}
true
}
}
impl Clone for RemoteNode {
fn clone(&self) -> RemoteNode {
let mut node = RemoteNode {
addr: self.addr().clone(),
objects: Vec::new(),
};
for obj in self.objects() {
node.add_object(obj.clone());
}
node
}
}
impl PartialEq for RemoteNode {
fn eq(&self, other: &Self) -> bool {
self.addr == other.addr
}
}
impl Eq for RemoteNode {}
impl Hash for RemoteNode {
fn hash<H: Hasher>(&self, state: &mut H) {
self.addr.hash(state);
}
}