holger_core/repository/
rust.rs

1use crate::RepositoryBackend;
2use std::any::Any;
3use anyhow::anyhow;
4use crate::{ArtifactFormat, ArtifactId, StorageEndpointInstance};
5
6/// Minimal RustRepo example
7pub struct RustRepo {
8    pub name: String,
9    pub in_backend: Option<StorageEndpointInstance>,
10    pub out_backend: StorageEndpointInstance,
11}
12
13impl RepositoryBackend for RustRepo {
14    fn name(&self) -> &str {
15        &self.name
16    }
17
18    fn format(&self) -> ArtifactFormat {
19        ArtifactFormat::Rust
20    }
21
22    fn is_writable(&self) -> bool {
23        self.in_backend.is_some()
24    }
25
26    fn fetch(&self, _id: &ArtifactId) -> anyhow::Result<Option<Vec<u8>>> {
27        Ok(None)
28    }
29
30    fn put(&self, _id: &ArtifactId, _data: &[u8]) -> anyhow::Result<()> {
31        if self.in_backend.is_none() {
32            return Err(anyhow!("Repository '{}' is read-only", self.name));
33        }
34        Ok(())
35    }
36
37    fn as_any(&self) -> &dyn Any {
38        self
39    }
40
41
42    fn handle_http2_request(
43        &self,
44        suburl: &str,
45        body: &[u8],
46    ) -> anyhow::Result<(u16, Vec<(String, String)>, Vec<u8>)> {
47        let _ = body; // currently unused
48
49        let parts: Vec<&str> = suburl.trim_start_matches('/').split('/').collect();
50
51        match parts.as_slice() {
52            ["crates", crate_name, version, "download"] => {
53                println!("Download request: crate={} version={}", crate_name, version);
54                Ok((
55                    200,
56                    vec![("Content-Type".into(), "application/octet-stream".into())],
57                    b"OK".to_vec(),
58                ))
59            }
60
61            ["config.json"] => {
62                println!("config.json requested");
63                let json = r#"{"dl":"https://127.0.0.1:8443/crates"}"#;
64                Ok((
65                    200,
66                    vec![("Content-Type".into(), "application/json".into())],
67                    json.as_bytes().to_vec(),
68                ))
69            }
70
71            ["index", crate_name] => {
72                println!("Index request: crate={}", crate_name);
73                Ok((
74                    200,
75                    vec![("Content-Type".into(), "text/plain".into())],
76                    b"dummy-index-content".to_vec(),
77                ))
78            }
79
80            _ => {
81                println!("Unhandled path: {}", suburl);
82                Ok((404, Vec::new(), b"Not found".to_vec()))
83            }
84        }
85    }
86
87}
88
89