Skip to main content

lfsx_server/storage/backend/
meta.rs

1use super::{Backend, Store};
2use crate::error::Error;
3
4const DIRECTORY: &str = ".lfsx";
5
6impl Store {
7    pub async fn read_meta(&self, name: &str) -> Result<Option<Vec<u8>>, Error> {
8        match &self.backend {
9            Backend::Local(store) => {
10                match tokio::fs::read(store.root.join(DIRECTORY).join(name)).await {
11                    Ok(bytes) => Ok(Some(bytes)),
12                    Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(None),
13                    Err(error) => Err(error.into()),
14                }
15            }
16            Backend::Bucket { bucket, .. } => bucket.read_meta(&key(name)).await,
17        }
18    }
19
20    pub async fn write_meta(&self, name: &str, bytes: Vec<u8>) -> Result<(), Error> {
21        match &self.backend {
22            Backend::Local(store) => {
23                let directory = store.root.join(DIRECTORY);
24                tokio::fs::create_dir_all(&directory).await?;
25                let staged = directory.join(format!("{name}.part"));
26                tokio::fs::write(&staged, bytes).await?;
27                tokio::fs::rename(&staged, directory.join(name)).await?;
28                Ok(())
29            }
30            Backend::Bucket { bucket, .. } => bucket.write_meta(&key(name), bytes).await,
31        }
32    }
33
34    pub async fn delete_meta(&self, name: &str) -> Result<(), Error> {
35        match &self.backend {
36            Backend::Local(store) => {
37                match tokio::fs::remove_file(store.root.join(DIRECTORY).join(name)).await {
38                    Err(error) if error.kind() != std::io::ErrorKind::NotFound => Err(error.into()),
39                    _ => Ok(()),
40                }
41            }
42            Backend::Bucket { bucket, .. } => bucket.delete_meta(&key(name)).await,
43        }
44    }
45}
46
47fn key(name: &str) -> String {
48    format!("{DIRECTORY}/{name}")
49}