I am trying to implement a couple traits
One is a Server Trait that implements ping, the other is a Cluster of servers that should hold the Server trait objects
I have some stripped down sample code below.
use async_trait::async_trait;
use tokio::sync::{RwLock};
use std::sync::{Arc};
use std::collections::HashMap;
use std::fmt;
#[async_trait]
pub trait ServerCluster {
type Error;
// Add a server
async fn add_server<T: Server + Send + Sync>(&self, server: T)
-> Result<(), Self::Error>;
}
#[async_trait]
pub trait Server {
type Error;
// Unique id to identify the server
fn id(&self) -> &str;
// Ping server, returns status and message
async fn ping(&self) -> Result<ServerPing, Self::Error>;
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug)]
pub enum ServerStatus {
READY,
NOTREADY,
UNREACHABLE,
MAINTENANCE,
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct ServerPing {
pub status: ServerStatus,
pub message: String,
}
struct MyServerCluster{
server_list:Arc<RwLock<HashMap<String, Box<dyn Server<Error = ServerError>>>>>,
}
#[async_trait]
impl ServerCluster for MyServerCluster{
type Error = ServerClusterError;
// Add a collection (espion server)
async fn add_server<T: Server + Send + Sync>(
&self,
server: T,
) -> Result<(), Self::Error> {
// Get a write lock on the server list
let cluster_map = &self.server_list.write().await;
cluster_map.insert(server.id().to_string(), Box::new(server));
Ok(())
}
}
struct MyServer {
id:String
}
#[async_trait]
impl Server for MyServer {
type Error = ServerError;
// Unique id to identify the server
fn id(&self) -> &str {
self.id.as_str()
}
// Ping server, returns status and message
async fn ping(&self) -> Result<ServerPing, Self::Error>{
Ok(ServerPing{
status: ServerStatus::UNREACHABLE,
message: "Cant open connection".to_string()
})
}
}
#[derive(Debug, Clone)]
struct ServerError;
impl fmt::Display for ServerError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "There was an error")
}
}
#[derive(Debug, Clone)]
struct ServerClusterError;
impl fmt::Display for ServerClusterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "There was an error")
}
}
fn main() {
println!("Some stuff");
}
I have been messing with the HashMap type and the insert but I am struggling with the following error
error[E0271]: type mismatch resolving `<T as Server>::Error == ServerError`
--> src/main.rs:61:53
|
61 | cluster_map.insert(server.id().to_string(), Box::new(server));
| ^^^^^^^^^^^^^^^^ expected struct `ServerError`, found associated type
|
= note: expected struct `ServerError`
found associated type `<T as Server>::Error`
= help: consider constraining the associated type `<T as Server>::Error` to `ServerError`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
= note: required for the cast to the object type `dyn Server<Error = ServerError>`
Can someone help me parse what this error is trying to tell me?
There seems to be an issue with the Error associated type but I am unsure what I need to change.
Is this the right approach to be using for traits or am I going about this wrong?