use super::{Registry, RegistryError};
use crate::types::{IndexEntry, PublishMetadata};
#[derive(Clone)]
pub struct OverlayRegistry<Top, Bottom>
where
Top: Registry,
Bottom: Registry,
{
pub top: Top,
pub bottom: Bottom,
}
impl<Top, Bottom> OverlayRegistry<Top, Bottom>
where
Top: Registry,
Bottom: Registry,
{
pub fn new(top: Top, bottom: Bottom) -> Self {
Self { top, bottom }
}
}
impl<Top, Bottom> Registry for OverlayRegistry<Top, Bottom>
where
Top: Registry,
Bottom: Registry,
{
async fn lookup(&self, crate_name: &str) -> Result<Vec<IndexEntry>, RegistryError> {
let top_entries = self.top.lookup(crate_name).await?;
let bottom_entries = self.bottom.lookup(crate_name).await?;
let mut merged: Vec<IndexEntry> = bottom_entries;
for top_entry in top_entries {
merged.retain(|e| e.vers != top_entry.vers);
merged.push(top_entry);
}
Ok(merged)
}
async fn download(&self, crate_name: &str, version: &str) -> Result<Vec<u8>, RegistryError> {
match self.top.download(crate_name, version).await {
Ok(data) => return Ok(data),
Err(RegistryError::NotFound) => {
}
Err(e) => return Err(e),
}
self.bottom.download(crate_name, version).await
}
async fn publish(
&self,
metadata: PublishMetadata,
crate_data: &[u8],
auth_token: Option<&str>,
) -> Result<String, RegistryError> {
self.top.publish(metadata, crate_data, auth_token).await
}
}