cosmic_space/artifact/
synch.rs1use 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}