lintel_validate/
registry.rs1use lintel_schema_cache::SchemaCache;
2use schema_catalog::Catalog;
3
4pub const DEFAULT_REGISTRY: &str = "https://catalog.lintel.tools/catalog.json";
6
7pub fn resolve_urls(url: &str) -> Vec<String> {
17 if let Some(rest) = url.strip_prefix("github:") {
18 let parts: Vec<&str> = rest.splitn(3, '/').collect();
20 if parts.len() == 3 {
21 vec![format!(
22 "https://raw.githubusercontent.com/{}/{}/{}/catalog.json",
23 parts[0], parts[1], parts[2]
24 )]
25 } else {
26 vec![
28 format!("https://raw.githubusercontent.com/{rest}/main/catalog.json"),
29 format!("https://raw.githubusercontent.com/{rest}/master/catalog.json"),
30 ]
31 }
32 } else {
33 vec![url.to_string()]
34 }
35}
36
37pub async fn fetch(
47 cache: &SchemaCache,
48 url: &str,
49) -> Result<Catalog, Box<dyn core::error::Error + Send + Sync>> {
50 let urls = resolve_urls(url);
51 let mut last_err: Option<Box<dyn core::error::Error + Send + Sync>> = None;
52 for resolved in &urls {
53 match cache.fetch(resolved).await {
54 Ok((value, _status)) => {
55 let catalog = schema_catalog::parse_catalog_value(value)?;
56 return Ok(catalog);
57 }
58 Err(e) => last_err = Some(e),
59 }
60 }
61 Err(last_err.unwrap_or_else(|| "no URLs to try".into()))
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn github_shorthand_tries_main_then_master() {
70 let urls = resolve_urls("github:my-org/my-schemas");
71 assert_eq!(urls.len(), 2);
72 assert_eq!(
73 urls[0],
74 "https://raw.githubusercontent.com/my-org/my-schemas/main/catalog.json"
75 );
76 assert_eq!(
77 urls[1],
78 "https://raw.githubusercontent.com/my-org/my-schemas/master/catalog.json"
79 );
80 }
81
82 #[test]
83 fn github_shorthand_with_explicit_branch() {
84 let urls = resolve_urls("github:lintel-rs/lintel/master");
85 assert_eq!(urls.len(), 1);
86 assert_eq!(
87 urls[0],
88 "https://raw.githubusercontent.com/lintel-rs/lintel/master/catalog.json"
89 );
90 }
91
92 #[test]
93 fn plain_url_unchanged() {
94 let url = "https://example.com/catalog.json";
95 assert_eq!(resolve_urls(url), vec![url]);
96 }
97
98 #[test]
99 fn default_registry_is_plain_url() {
100 let urls = resolve_urls(DEFAULT_REGISTRY);
101 assert_eq!(urls.len(), 1);
102 assert_eq!(urls[0], "https://catalog.lintel.tools/catalog.json");
103 }
104}