iota_storage/object_store/http/
local.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::{fmt, fs, fs::File, io::Read, path::PathBuf};
6
7use anyhow::{Context, Result, anyhow};
8use async_trait::async_trait;
9use bytes::Bytes;
10use object_store::path::Path;
11
12use crate::object_store::{ObjectStoreGetExt, util::path_to_filesystem};
13
14pub struct LocalStorage {
15    root: PathBuf,
16}
17
18impl LocalStorage {
19    pub fn new(directory: &std::path::Path) -> Result<Self> {
20        let path = fs::canonicalize(directory).context(anyhow!("Unable to canonicalize"))?;
21        fs::create_dir_all(&path).context(anyhow!(
22            "Failed to create local directory: {}",
23            path.display()
24        ))?;
25        Ok(LocalStorage { root: path })
26    }
27}
28
29impl fmt::Display for LocalStorage {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        write!(f, "local:{}", self.root.display())
32    }
33}
34
35#[async_trait]
36impl ObjectStoreGetExt for LocalStorage {
37    async fn get_bytes(&self, location: &Path) -> Result<Bytes> {
38        let path_to_filesystem = path_to_filesystem(self.root.clone(), location)?;
39        let handle = tokio::task::spawn_blocking(move || {
40            let mut f = File::open(path_to_filesystem)
41                .map_err(|e| anyhow!("Failed to open file with error: {}", e.to_string()))?;
42            let mut buf = vec![];
43            f.read_to_end(&mut buf)
44                .context(anyhow!("Failed to read file"))?;
45            Ok(buf.into())
46        });
47        handle.await?
48    }
49}