loadsmith_registry/
lib.rs1use std::{collections::HashMap, fmt::Debug, pin::Pin};
9
10use loadsmith_core::{Checksum, Dependency, FileUrl, PackageId, PackageRef, Version};
11
12mod error;
13
14mod registries;
15
16pub use error::{Error, Result};
17pub use registries::*;
18use serde::de::DeserializeOwned;
19
20#[derive(Debug, Clone)]
21pub struct VersionInfo {
22 pub version: Version,
23}
24
25#[derive(Debug, Clone)]
26pub struct ResolvedVersion {
27 pub url: FileUrl,
28 pub size: Option<u64>,
29 pub checksum: Option<Checksum>,
30 pub deps: Vec<Dependency>,
31}
32
33pub trait Registry: Debug + Send + Sync {
34 fn version_info<'a>(
35 &'a self,
36 id: &'a PackageId,
37 metadata: Option<&'a serde_json::Value>,
38 ) -> Pin<Box<dyn Future<Output = Result<Vec<VersionInfo>>> + 'a>>;
39
40 fn resolve<'a>(
41 &'a self,
42 ref_: &'a PackageRef,
43 metadata: Option<&'a serde_json::Value>,
44 ) -> Pin<Box<dyn Future<Output = Result<ResolvedVersion>> + 'a>>;
45
46 fn revalidate_checksum<'a>(
47 &'a self,
48 ref_: &'a PackageRef,
49 metadata: Option<&'a serde_json::Value>,
50 ) -> Result<Option<Checksum>> {
51 let _ = (ref_, metadata);
52 Ok(None)
53 }
54}
55
56#[derive(Debug)]
57pub struct RegistrySet {
58 registries: HashMap<String, Box<dyn Registry>>,
59}
60
61impl Default for RegistrySet {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67impl RegistrySet {
68 pub fn new() -> Self {
69 Self {
70 registries: HashMap::new(),
71 }
72 }
73
74 pub fn add<R: Registry + 'static>(&mut self, id: impl Into<String>, registry: R) {
75 self.registries.insert(id.into(), Box::new(registry));
76 }
77
78 pub fn get(&self, id: &str) -> Option<&dyn Registry> {
79 self.registries.get(id).map(|r| r.as_ref())
80 }
81}
82
83pub fn read_metadata_or_default<T: DeserializeOwned + Default>(
84 metadata: Option<&serde_json::Value>,
85) -> Result<T> {
86 match metadata {
87 Some(metadata) => read_metadata_some(metadata),
88 None => Ok(T::default()),
89 }
90}
91
92pub fn read_metadata<T: DeserializeOwned>(metadata: Option<&serde_json::Value>) -> Result<T> {
93 match metadata {
94 Some(metadata) => read_metadata_some(metadata),
95 None => Err(Error::MissingMetadata),
96 }
97}
98
99fn read_metadata_some<T: DeserializeOwned>(metadata: &serde_json::Value) -> Result<T> {
100 serde_json::from_value(metadata.clone()).map_err(Error::InvalidMetadata)
101}