remote_hash_map 0.2.6

Remote hash map
use std::io;

use tokio::fs::{metadata, File, OpenOptions};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

use crate::common::utils::data_file;

#[derive(Debug)]
pub struct Storage {
    file: File,
}

impl Storage {
    pub async fn new(id: &str) -> tokio::io::Result<Self> {
        let data_file = data_file(id);
        if Self::not_exists(&data_file).await? {
            Self::create(&data_file).await?
        }

        Ok(Self { file: Self::open(&data_file).await? })
    }

    async fn not_exists(data_file: &str) -> std::io::Result<bool> {
        match metadata(data_file).await {
            Ok(_) => Ok(false),
            Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(true),
            Err(e) => Err(e),
        }
    }

    async fn create(data_file: &str) -> tokio::io::Result<()> {
        File::create(data_file).await?;
        Ok(())
    }

    pub async fn open(data_file: &str) -> tokio::io::Result<File> {
        let file = OpenOptions::new().append(true).read(true).open(data_file).await?;
        Ok(file)
    }

    pub async fn save(&mut self, data: &str) -> tokio::io::Result<()> {
        self.file.write_all(data.as_bytes()).await?;
        Ok(())
    }

    pub async fn load(&mut self) -> tokio::io::Result<String> {
        let mut contents = String::new();
        self.file.read_to_string(&mut contents).await?;
        Ok(contents)
    }
}