cosmic_space/artifact/
synch.rs

1use crate::artifact::ArtRef;
2use crate::config::mechtron::MechtronConfig;
3use crate::{Bin, BindConfig, SpaceErr, Stub};
4use dashmap::DashMap;
5use std::sync::Arc;
6use crate::point::Point;
7
8#[derive(Clone)]
9pub struct ArtifactApi {
10    binds: Arc<DashMap<Point, Arc<BindConfig>>>,
11    mechtrons: Arc<DashMap<Point, Arc<MechtronConfig>>>,
12    raw: Arc<DashMap<Point, Arc<Vec<u8>>>>,
13    fetcher: Arc<dyn ArtifactFetcher>,
14}
15
16impl ArtifactApi {
17    pub fn new(fetcher: Arc<dyn ArtifactFetcher>) -> Self {
18        Self {
19            binds: Arc::new(DashMap::new()),
20            mechtrons: Arc::new(DashMap::new()),
21            raw: Arc::new(DashMap::new()),
22            fetcher,
23        }
24    }
25
26    pub fn mechtron(&self, point: &Point) -> Result<ArtRef<MechtronConfig>, SpaceErr> {
27        {
28            if self.mechtrons.contains_key(point) {
29                let mechtron = self.mechtrons.get(point).unwrap().clone();
30                return Ok(ArtRef::new(mechtron, point.clone()));
31            }
32        }
33
34        let mechtron: Arc<MechtronConfig> = Arc::new(self.fetch(point)?);
35        self.mechtrons.insert(point.clone(), mechtron.clone());
36        return Ok(ArtRef::new(mechtron, point.clone()));
37    }
38
39    pub fn bind(&self, point: &Point) -> Result<ArtRef<BindConfig>, SpaceErr> {
40        {
41            if self.binds.contains_key(point) {
42                let bind = self.binds.get(point).unwrap().clone();
43                return Ok(ArtRef::new(bind, point.clone()));
44            }
45        }
46
47        let bind: Arc<BindConfig> = Arc::new(self.fetch(point)?);
48        {
49            self.binds.insert(point.clone(), bind.clone());
50        }
51        return Ok(ArtRef::new(bind, point.clone()));
52    }
53
54    pub fn raw(&self, point: &Point) -> Result<ArtRef<Vec<u8>>, SpaceErr> {
55        if self.binds.contains_key(point) {
56            let bin = self.raw.get(point).unwrap().clone();
57            return Ok(ArtRef::new(bin, point.clone()));
58        }
59
60        let bin = self.fetcher.fetch(point)?;
61
62        self.raw.insert(point.clone(), bin.clone());
63
64        return Ok(ArtRef::new(bin, point.clone()));
65    }
66
67    fn fetch<A>(&self, point: &Point) -> Result<A, SpaceErr>
68    where
69        A: TryFrom<Bin, Error = SpaceErr>,
70    {
71        if !point.has_bundle() {
72            return Err("point is not from a bundle".into());
73        }
74        let bin = self.fetcher.fetch(point)?;
75        Ok(A::try_from(bin)?)
76    }
77}
78#[async_trait]
79pub trait ArtifactFetcher: Send + Sync {
80    fn stub(&self, point: &Point) -> Result<Stub, SpaceErr>;
81    fn fetch(&self, point: &Point) -> Result<Bin, SpaceErr>;
82}