mod peer;
pub(crate) mod remote;
use std::{sync::Arc, time::Duration};
use async_trait::async_trait;
pub use peer::{
ExchangeBounds, Failure, Message, Outcome, Peer, PeerError, Request, Started, StillWorking,
};
pub type OnChange = Arc<dyn Fn() + Send + Sync>;
#[async_trait]
pub trait AgentResolver: Send + Sync {
async fn resolve(&self, name: &str) -> Result<Resolved, Unresolved>;
fn route(&self, _name: &str) -> Route {
Route::Maybe
}
fn taught(&self) -> Taught {
Taught::default()
}
fn on_change(&self, _hook: OnChange) {}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Route {
Known,
Unknown,
Maybe,
Backoff(Duration),
Refused(String),
}
#[derive(Clone)]
#[non_exhaustive]
pub struct Resolved {
pub peer: Arc<dyn Peer>,
pub id: String,
pub name: String,
pub endpoint: String,
}
impl std::fmt::Debug for Resolved {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Resolved")
.field("id", &self.id)
.field("name", &self.name)
.field("endpoint", &self.endpoint)
.finish_non_exhaustive()
}
}
impl Resolved {
pub fn new(peer: Arc<dyn Peer>, name: impl Into<String>, endpoint: impl Into<String>) -> Self {
let name = name.into();
Self {
peer,
id: name.clone(),
name,
endpoint: endpoint.into(),
}
}
#[must_use]
pub fn with_id(self, id: impl Into<String>) -> Self {
Self {
id: id.into(),
..self
}
}
#[must_use]
pub fn with_endpoint(self, endpoint: impl Into<String>) -> Self {
Self {
endpoint: endpoint.into(),
..self
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Unresolved {
Unknown,
Backoff(Duration),
Unreachable {
error: String,
retry_in: Option<Duration>,
},
Refused(String),
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[non_exhaustive]
pub struct Taught {
pub agents: Vec<TaughtAgent>,
pub note: Option<String>,
}
impl Taught {
#[must_use]
pub fn with_agent(mut self, agent: TaughtAgent) -> Self {
self.agents.push(agent);
self
}
#[must_use]
pub fn with_note(self, note: impl Into<String>) -> Self {
Self {
note: Some(note.into()),
..self
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct TaughtAgent {
pub name: String,
pub summary: Option<String>,
}
impl TaughtAgent {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
summary: None,
}
}
#[must_use]
pub fn with_summary(self, summary: impl Into<String>) -> Self {
Self {
summary: Some(summary.into()),
..self
}
}
}