use crate::config;
use std::fs;
use std::path::{Path, PathBuf};
use tokio::fs::File;
use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncSeekExt, SeekFrom};
use tracing::info;
const DEFAULT_DIR_NAME: &str = "content";
pub struct Content {
dir: PathBuf,
}
impl Content {
pub fn new(data_dir: &Path) -> super::Result<Content> {
let dir = data_dir.join(config::NAME).join(DEFAULT_DIR_NAME);
fs::create_dir_all(&dir)?;
info!("create content directory: {:?}", dir);
Ok(Content { dir })
}
pub async fn read_piece(
&self,
task_id: &str,
offset: u64,
length: u64,
) -> super::Result<impl AsyncRead> {
let mut f = File::open(self.dir.join(task_id)).await?;
f.seek(SeekFrom::Start(offset)).await?;
Ok(f.take(length))
}
pub async fn write_piece<R: AsyncRead + Unpin>(
&self,
task_id: &str,
offset: u64,
reader: &mut R,
) -> super::Result<u64> {
let mut f = File::open(self.dir.join(task_id)).await?;
f.seek(SeekFrom::Start(offset)).await?;
Ok(io::copy(reader, &mut f).await?)
}
}