1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::{
4 collections::HashSet,
5 fmt,
6 hash::{Hash, Hasher},
7};
8use url::Url;
9
10#[derive(Debug, Clone, Eq, Serialize, Deserialize)]
12pub struct Origin {
13 name: String,
14 url: Url,
15}
16
17impl Origin {
18 pub fn new(name: String, url: Url) -> Self {
20 Self { name, url }
21 }
22
23 pub fn name(&self) -> &str {
25 &self.name
26 }
27
28 pub fn url(&self) -> &Url {
30 &self.url
31 }
32}
33
34impl PartialEq for Origin {
35 fn eq(&self, other: &Self) -> bool {
36 self.url == other.url
37 }
38}
39
40impl Hash for Origin {
41 fn hash<H: Hasher>(&self, state: &mut H) {
42 self.url.hash(state);
43 }
44}
45
46impl fmt::Display for Origin {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "{} ({})", self.name, self.url)
49 }
50}
51
52impl From<Url> for Origin {
53 fn from(url: Url) -> Self {
54 let name = url.authority().to_owned();
55 Self { name, url }
56 }
57}
58
59#[async_trait]
61pub trait RemoteOrigins {
62 type Error: std::error::Error + std::fmt::Debug;
64
65 async fn list_servers(&self) -> Result<HashSet<Origin>, Self::Error>;
67
68 async fn add_server(&mut self, origin: Origin)
70 -> Result<(), Self::Error>;
71
72 async fn replace_server(
74 &mut self,
75 old_origin: &Origin,
76 new_origin: Origin,
77 ) -> Result<(), Self::Error>;
78
79 async fn remove_server(
81 &mut self,
82 origin: &Origin,
83 ) -> Result<(), Self::Error>;
84}