1use crate::actors::provider_session::ProviderLink;
2use rill_protocol::io::provider::{Description, Path};
5use rill_protocol::pathfinder::{Pathfinder, Record};
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9pub struct ValidPath(pub Path);
11
12pub struct Occupied {
13 pub path: Path,
14}
15
16pub struct WasEmpty {
17 pub path: Path,
18}
19
20#[derive(Debug, Clone)]
21pub struct Registry {
22 inner: Arc<RwLock<RegistryInner>>,
23}
24
25impl Registry {
26 #[allow(clippy::new_without_default)]
27 pub fn new() -> Self {
28 let inner = RegistryInner::new();
29 Self {
30 inner: Arc::new(RwLock::new(inner)),
31 }
32 }
33
34 pub async fn register_provider(
35 &mut self,
36 path: Path,
37 _description: Description,
38 provider: ProviderLink,
39 ) -> Result<ProviderEntry, Occupied> {
40 log::debug!("Registering provider: {}", path);
41 let mut inner = self.inner.write().await;
42 let record = inner.providers.dig(path.clone());
43 if !record.has_link() {
44 record.set_link(provider);
45 let entry = ProviderEntry {
47 inner: self.inner.clone(),
48 path,
49 };
50 Ok(entry)
51 } else {
52 Err(Occupied { path })
53 }
54 }
55
56 pub async fn find_provider(&self, path: &ValidPath) -> Option<(ProviderLink, Path)> {
57 let inner = self.inner.read().await;
58 let discovered = inner.providers.discover(&path.0);
59 discovered
60 .record
61 .get_link()
62 .map(ProviderLink::clone)
63 .map(move |link| (link, discovered.remained_path))
64 }
65}
66
67#[derive(Debug)]
68pub struct RegistryInner {
69 providers: Pathfinder<ProviderLink>,
70 }
72
73impl RegistryInner {
74 fn new() -> Self {
75 let providers = Pathfinder::new();
76 Self {
78 providers,
79 }
81 }
82}
83
84pub struct ProviderEntry {
85 inner: Arc<RwLock<RegistryInner>>,
86 path: Path,
87}
88
89impl ProviderEntry {
90 pub async fn unregister_provider(self) -> Result<(), WasEmpty> {
91 let mut inner = self.inner.write().await;
92 let path = self.path.clone();
93 let link = inner.providers.find_mut(&path).and_then(Record::take_link);
94 if link.is_some() {
95 Ok(())
97 } else {
98 Err(WasEmpty { path: self.path })
99 }
100 }
101}