Skip to main content

sofie_db/
remote.rs

1//! Where a split app serves the apps it left, shared by its server and their clients.
2
3use sofie_auth::Acting;
4
5pub const PRINCIPAL_HEADER: &str = "sofie-principal";
6pub const CONTRACTS_PATH: &str = "/_sofie/contracts/";
7pub const LOOKUPS_PATH: &str = "/_sofie/lookups/";
8pub const FEED_PATH: &str = "/_sofie/feed";
9
10/// Both apps compile the DTO from its contract crate, so both name it alike.
11#[must_use]
12pub fn lookup_name<D>() -> &'static str {
13    std::any::type_name::<D>()
14}
15
16#[cfg_attr(not(feature = "live"), expect(unused_variables))]
17pub fn read_through(app: &str) {
18    #[cfg(feature = "live")]
19    crate::live::read_remote(app);
20}
21
22tokio::task_local! {
23    static ACTING: Option<Acting>;
24}
25
26pub async fn acting_as<F: Future>(acting: Option<Acting>, work: F) -> F::Output {
27    ACTING.scope(acting, work).await
28}
29
30#[must_use]
31pub fn acting() -> Option<Acting> {
32    ACTING.try_with(Clone::clone).ok().flatten()
33}
34
35#[cfg(test)]
36mod tests {
37    use sofie_core::Uuid;
38
39    use super::*;
40
41    #[tokio::test]
42    async fn work_acts_for_the_principal_of_its_scope_only() {
43        let customer = Acting {
44            area: "customer".to_owned(),
45            principal: Uuid::now_v7().unwrap(),
46        };
47
48        let inside = acting_as(Some(customer.clone()), async { acting() }).await;
49
50        assert_eq!(inside, Some(customer));
51        assert_eq!(acting(), None);
52    }
53}