use std::time::SystemTime;
extern crate chrono;
extern crate chrono_english;
extern crate chrono_humanize;
extern crate humantime;
extern crate futures;
use futures::prelude::*;
extern crate structopt;
use structopt::StructOpt;
extern crate strum;
#[macro_use]
extern crate strum_macros;
extern crate rand;
use rand::random;
extern crate dsf_core;
use dsf_core::error::Error;
use dsf_core::page::Page;
use dsf_core::types::*;
#[macro_use]
extern crate serde;
extern crate colored;
pub mod config;
pub use config::*;
pub mod data;
pub use data::*;
pub mod debug;
pub use debug::*;
pub mod peer;
pub use peer::*;
pub mod service;
pub use service::*;
pub mod replica;
pub use replica::*;
pub mod display;
mod helpers;
pub trait Rpc {
type Error;
fn exec(&mut self, req: Request) -> Box<dyn Future<Output = Result<Response, Self::Error>>>;
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Request {
req_id: u64,
kind: RequestKind,
}
impl Request {
pub fn new(kind: RequestKind) -> Self {
Self {
req_id: random(),
kind,
}
}
pub fn req_id(&self) -> u64 {
self.req_id
}
pub fn kind(&self) -> RequestKind {
self.kind.clone()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, StructOpt)]
pub struct ServiceIdentifier {
#[structopt(short = "i", long = "id", group = "identifier")]
pub id: Option<Id>,
#[structopt(short = "n", long = "index", group = "identifier")]
pub index: Option<usize>,
}
impl ServiceIdentifier {
pub fn id(id: Id) -> Self {
Self {
id: Some(id),
index: None,
}
}
pub fn index(index: usize) -> Self {
Self {
id: None,
index: Some(index),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, StructOpt)]
pub struct PageBounds {
#[structopt(long = "count")]
pub count: Option<usize>,
#[structopt(long = "offset")]
pub offset: Option<usize>,
}
#[derive(Debug, Clone, StructOpt)]
pub struct TimeBounds {
#[structopt(long, parse(try_from_str = timestamp_from_str))]
pub from: Option<SystemTime>,
#[structopt(long, parse(try_from_str = timestamp_from_str))]
pub until: Option<SystemTime>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, StructOpt)]
pub enum RequestKind {
#[structopt(name = "status")]
Status,
#[structopt(name = "peer")]
Peer(PeerCommands),
#[structopt(name = "service")]
Service(ServiceCommands),
#[structopt(name = "data")]
Data(DataCommands),
#[structopt(name = "config")]
Config(ConfigCommands),
#[structopt(name = "debug")]
Debug(DebugCommands),
#[structopt(name = "stream")]
Stream(SubscribeOptions),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Response {
req_id: u64,
kind: ResponseKind,
}
impl Response {
pub fn new(req_id: u64, kind: ResponseKind) -> Self {
Self { req_id, kind }
}
pub fn req_id(&self) -> u64 {
self.req_id
}
pub fn kind(&self) -> ResponseKind {
self.kind.clone()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ResponseKind {
None,
Status(StatusInfo),
Connected(ConnectInfo),
Peer(PeerInfo),
Peers(Vec<(Id, PeerInfo)>),
Service(ServiceInfo),
Services(Vec<ServiceInfo>),
Registered(RegisterInfo),
Located(LocateInfo),
Subscribed(Vec<SubscriptionInfo>),
Published(PublishInfo),
Datastore(Vec<(Id, Vec<Vec<u8>>)>),
Data(Vec<DataInfo>),
Pages(Vec<Page>),
Unrecognised,
Error(Error),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StatusInfo {
pub id: Id,
pub peers: usize,
pub services: usize,
}
pub use dsf_core::base::Body;
fn timestamp_from_str(s: &str) -> Result<SystemTime, chrono_english::DateError> {
let t =
chrono_english::parse_date_string(s, chrono::Local::now(), chrono_english::Dialect::Uk)?;
Ok(t.into())
}