demo/
demo.rs

1use async_trait::async_trait;
2use std::collections::HashMap;
3use std::sync::Arc;
4use supply_demand::{Demand, ErasedSupplier, Scope, Supplier, SupplierRegistry};
5use tokio::time::{Duration, sleep};
6
7/// Supplier for "valueA": returns i32, takes no input
8struct ValueASupplier;
9#[async_trait]
10impl Supplier for ValueASupplier {
11    type Input = ();
12    type Output = i32;
13    async fn supply(&self, _input: (), _scope: Arc<Scope>) -> i32 {
14        10
15    }
16}
17
18/// Alternative supplier "altA": returns i32, takes no input, but is delayed
19struct AltValueASupplier;
20#[async_trait]
21impl Supplier for AltValueASupplier {
22    type Input = ();
23    type Output = i32;
24    async fn supply(&self, _input: (), _scope: Arc<Scope>) -> i32 {
25        sleep(Duration::from_millis(2000)).await;
26        123
27    }
28}
29
30/// Supplier B: asks for "valueA" (with override), adds 5, returns i32
31struct ValueBSupplier {
32    alt: Arc<dyn ErasedSupplier>, // This could also just be Arc<AltValueASupplier>
33}
34#[async_trait]
35impl Supplier for ValueBSupplier {
36    type Input = ();
37    type Output = i32;
38    async fn supply(&self, _input: (), scope: Arc<Scope>) -> i32 {
39        // Construct override registry using its internally owned alt supplier
40        let mut overrides = SupplierRegistry::new();
41        overrides.insert("valueA".to_string(), self.alt.clone());
42        let demand = Demand {
43            type_: "valueA".to_string(),
44            override_suppliers: Some(overrides),
45        };
46        let va: i32 = scope.demand(demand, Box::new(())).await;
47        va + 5
48    }
49}
50
51impl ValueBSupplier {
52    /// Convenience constructor to bundle the alt supplier privately
53    fn new() -> Self {
54        Self {
55            alt: Arc::new(AltValueASupplier),
56        }
57    }
58}
59
60/// The root supplier, asks for valueA and valueB, combines results.
61struct RootSupplier;
62#[async_trait]
63impl Supplier for RootSupplier {
64    type Input = ();
65    type Output = i32;
66    async fn supply(&self, _input: (), scope: Arc<Scope>) -> i32 {
67        let va: i32 = scope
68            .demand(
69                Demand {
70                    type_: "valueA".to_string(),
71                    override_suppliers: None,
72                },
73                Box::new(()),
74            )
75            .await;
76        let vb: i32 = scope
77            .demand(
78                Demand {
79                    type_: "valueB".to_string(),
80                    override_suppliers: None,
81                },
82                Box::new(()),
83            )
84            .await;
85        va + vb
86    }
87}
88
89#[tokio::main]
90async fn main() {
91    // Create registry: valueA points to ValueASupplier, valueB to ValueBSupplier,
92    // B owns its internal alternative supplier privately
93    let mut registry: SupplierRegistry = HashMap::new();
94
95    registry.insert("valueA".to_string(), Arc::new(ValueASupplier));
96    registry.insert("valueB".to_string(), Arc::new(ValueBSupplier::new()));
97
98    let scope = Arc::new(Scope {
99        registry: Arc::new(registry),
100    });
101
102    let root = RootSupplier;
103    let result = root.supply((), scope.clone()).await;
104    assert_eq!(result, 10 + 128);
105    println!("Sum of valueA and valueB: {}", result); // Should print 138 after 2000
106}