ograf_core/directory.rs
1//! Which renderers exist beyond the ones connected right now — a second
2//! Dependency Inversion seam next to [`AccessControl`](crate::access::AccessControl).
3//! Core itself keeps no storage: it remembers disconnected renderers only for
4//! the life of the process. A consumer with a database (or a config file, or
5//! an NMOS registry) implements [`RendererDirectory`] so controllers can see
6//! renderers that are offline, or haven't connected yet — reported with
7//! `status: ERROR`.
8
9use async_trait::async_trait;
10
11use crate::models::RendererId;
12
13/// A renderer a [`RendererDirectory`] knows about.
14#[derive(Debug, Clone)]
15#[non_exhaustive]
16pub struct KnownRenderer {
17 pub id: RendererId,
18 pub name: String,
19 pub description: Option<String>,
20}
21
22impl KnownRenderer {
23 /// Core's renderer ids are also their names, so `id` fills both.
24 pub fn new(id: impl Into<RendererId>) -> Self {
25 let id = id.into();
26 Self { name: id.clone(), id, description: None }
27 }
28
29 pub fn with_description(mut self, description: impl Into<String>) -> Self {
30 self.description = Some(description.into());
31 self
32 }
33}
34
35#[async_trait]
36pub trait RendererDirectory: Send + Sync {
37 /// Every renderer this directory knows, connected or not. Core merges
38 /// them with its own sessions; a renderer that's connected is reported
39 /// from its live session, whatever the directory says.
40 async fn known_renderers(&self) -> Vec<KnownRenderer>;
41}
42
43/// No directory — only connected renderers and ones that disconnected since
44/// the process started are listed. The default.
45pub struct NoDirectory;
46
47#[async_trait]
48impl RendererDirectory for NoDirectory {
49 async fn known_renderers(&self) -> Vec<KnownRenderer> {
50 Vec::new()
51 }
52}