pub use super::support::Config;
use super::support::{Endpoint, Network, ServiceHandle, ServiceImpl};
use maidsafe_utilities::event_sender;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::cell::{RefCell, RefMut};
use std::collections::HashSet;
use std::hash::Hash;
use std::net::{IpAddr, SocketAddr};
use std::rc::Rc;
use std::{fmt, thread};
pub const LISTENER_PORT: u16 = 5485;
pub fn read_config_file() -> Result<Config, CrustError> {
Ok(Config::new())
}
pub struct Service<UID: Uid>(Rc<RefCell<ServiceImpl<UID>>>, Network<UID>);
impl<UID: Uid> Service<UID> {
pub fn new(
handle: ServiceHandle<UID>,
event_sender: CrustEventSender<UID>,
uid: UID,
) -> Result<Self, CrustError> {
Self::with_handle(&handle, event_sender, uid)
}
pub fn with_config(
handle: ServiceHandle<UID>,
event_sender: CrustEventSender<UID>,
_config: Config,
uid: UID,
) -> Result<Self, CrustError> {
Self::with_handle(&handle, event_sender, uid)
}
pub fn with_handle(
handle: &ServiceHandle<UID>,
event_sender: CrustEventSender<UID>,
uid: UID,
) -> Result<Self, CrustError> {
let network = handle.0.borrow().network.clone();
let service = Service(Rc::clone(&handle.0), network);
service.lock().start(event_sender, uid);
Ok(service)
}
pub fn restart(&self, event_sender: CrustEventSender<UID>, uid: UID) {
self.lock().restart(event_sender, uid)
}
pub fn start_bootstrap(
&mut self,
blacklist: HashSet<SocketAddr>,
user: CrustUser,
) -> Result<(), CrustError> {
self.lock().start_bootstrap(blacklist, user);
Ok(())
}
pub fn stop_bootstrap(&mut self) -> Result<(), CrustError> {
Ok(())
}
pub fn start_service_discovery(&mut self) {
trace!(target: "crust", "[MOCK] start_service_discovery not implemented in mock.");
}
pub fn set_service_discovery_listen(&self, _listen: bool) {
trace!(target: "crust", "[MOCK] set_service_discovery_listen not implemented in mock.");
}
pub fn set_accept_bootstrap(&mut self, accept: bool) -> Result<(), CrustError> {
self.lock().set_accept_bootstrap(accept);
Ok(())
}
pub fn has_peers_on_lan(&self) -> bool {
false
}
pub fn start_listening_tcp(&mut self) -> Result<(), CrustError> {
self.lock().start_listening_tcp(LISTENER_PORT);
Ok(())
}
pub fn stop_tcp_listener(&mut self) -> Result<(), CrustError> {
trace!(target: "crust", "[MOCK] stop_tcp_listener not implemented in mock.");
Err(CrustError)
}
pub fn prepare_connection_info(&self, result_token: u32) {
self.lock().prepare_connection_info(result_token)
}
pub fn connect(
&self,
our_info: PrivConnectionInfo<UID>,
their_info: PubConnectionInfo<UID>,
) -> Result<(), CrustError> {
self.lock().connect(our_info, their_info);
Ok(())
}
pub fn disconnect(&self, uid: &UID) -> bool {
self.lock().disconnect(uid)
}
pub fn send(&self, uid: &UID, data: Vec<u8>, _priority: u8) -> Result<(), CrustError> {
if self.lock().send_message(uid, data) {
Ok(())
} else {
Err(CrustError)
}
}
pub fn get_peer_ip_addr(&self, uid: &UID) -> Result<IpAddr, CrustError> {
self.lock().get_peer_ip_addr(uid).ok_or(CrustError)
}
pub fn is_connected(&self, uid: &UID) -> bool {
self.lock().is_peer_connected(uid)
}
pub fn is_peer_hard_coded(&self, _uid: &UID) -> bool {
true
}
pub fn id(&self) -> UID {
unwrap!(self.lock().uid)
}
fn lock(&self) -> RefMut<ServiceImpl<UID>> {
self.0.borrow_mut()
}
}
impl<UID: Uid> Drop for Service<UID> {
fn drop(&mut self) {
if !thread::panicking() {
self.lock().disconnect_all();
}
}
}
#[derive(Debug)]
pub enum Event<UID: Uid> {
BootstrapAccept(UID, CrustUser),
BootstrapConnect(UID, SocketAddr),
BootstrapFailed,
ListenerStarted(u16),
ListenerFailed,
ConnectionInfoPrepared(ConnectionInfoResult<UID>),
ConnectSuccess(UID),
ConnectFailure(UID),
LostPeer(UID),
NewMessage(UID, CrustUser, Vec<u8>),
WriteMsgSizeProhibitive(UID, Vec<u8>),
}
pub type CrustEventSender<UID> = event_sender::MaidSafeObserver<Event<UID>>;
pub trait Uid:
'static
+ Send
+ fmt::Debug
+ Clone
+ Copy
+ Eq
+ PartialEq
+ Ord
+ PartialOrd
+ Hash
+ Serialize
+ DeserializeOwned
{
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PrivConnectionInfo<UID> {
#[doc(hidden)]
pub id: UID,
#[doc(hidden)]
pub endpoint: Endpoint,
}
impl<UID: Uid> PrivConnectionInfo<UID> {
pub fn to_pub_connection_info(&self) -> PubConnectionInfo<UID> {
PubConnectionInfo {
id: self.id,
endpoint: self.endpoint,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct PubConnectionInfo<UID> {
#[doc(hidden)]
pub id: UID,
#[doc(hidden)]
pub endpoint: Endpoint,
}
impl<UID: Uid> PubConnectionInfo<UID> {
pub fn id(&self) -> UID {
self.id
}
}
#[derive(Debug)]
pub struct ConnectionInfoResult<UID: Uid> {
pub result_token: u32,
pub result: Result<PrivConnectionInfo<UID>, CrustError>,
}
#[derive(Debug)]
pub struct CrustError;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum CrustUser {
Node,
Client,
}