backend refactor file_system into warren domain
This commit is contained in:
@@ -32,10 +32,14 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let fs_config = FileSystemConfig::new(config.serve_dir);
|
let fs_config = FileSystemConfig::new(config.serve_dir);
|
||||||
let fs = FileSystem::new(fs_config)?;
|
let fs = FileSystem::new(fs_config)?;
|
||||||
let fs_service = domain::file_system::service::Service::new(fs, metrics, notifier);
|
let fs_service = domain::warren::service::file_system::Service::new(fs, metrics, notifier);
|
||||||
|
|
||||||
let warren_service =
|
let warren_service = domain::warren::service::warren::Service::new(
|
||||||
domain::warren::service::Service::new(postgres, metrics, notifier, fs_service.clone());
|
postgres,
|
||||||
|
metrics,
|
||||||
|
notifier,
|
||||||
|
fs_service.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
let server_config = HttpServerConfig::new(
|
let server_config = HttpServerConfig::new(
|
||||||
&config.server_address,
|
&config.server_address,
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
pub mod models;
|
|
||||||
pub mod ports;
|
|
||||||
pub mod service;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
pub mod file;
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
use super::models::file::{
|
|
||||||
CreateDirectoryError, CreateDirectoryRequest, CreateFileError, CreateFileRequest,
|
|
||||||
DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError, DeleteFileRequest, File,
|
|
||||||
FilePath, ListFilesError, ListFilesRequest,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait FileSystemService: Clone + Send + Sync + 'static {
|
|
||||||
fn list_files(
|
|
||||||
&self,
|
|
||||||
request: ListFilesRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<File>, ListFilesError>> + Send;
|
|
||||||
|
|
||||||
fn create_directory(
|
|
||||||
&self,
|
|
||||||
request: CreateDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, CreateDirectoryError>> + Send;
|
|
||||||
fn delete_directory(
|
|
||||||
&self,
|
|
||||||
request: DeleteDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteDirectoryError>> + Send;
|
|
||||||
|
|
||||||
fn create_file(
|
|
||||||
&self,
|
|
||||||
request: CreateFileRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, CreateFileError>> + Send;
|
|
||||||
fn delete_file(
|
|
||||||
&self,
|
|
||||||
request: DeleteFileRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteFileError>> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FileSystemRepository: Clone + Send + Sync + 'static {
|
|
||||||
fn list_files(
|
|
||||||
&self,
|
|
||||||
request: ListFilesRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<File>, ListFilesError>> + Send;
|
|
||||||
|
|
||||||
fn create_directory(
|
|
||||||
&self,
|
|
||||||
request: CreateDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, CreateDirectoryError>> + Send;
|
|
||||||
fn delete_directory(
|
|
||||||
&self,
|
|
||||||
request: DeleteDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteDirectoryError>> + Send;
|
|
||||||
|
|
||||||
fn create_file(
|
|
||||||
&self,
|
|
||||||
request: CreateFileRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, CreateFileError>> + Send;
|
|
||||||
fn delete_file(
|
|
||||||
&self,
|
|
||||||
request: DeleteFileRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteFileError>> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FileSystemMetrics: Clone + Send + Sync + 'static {
|
|
||||||
fn record_list_files_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_list_files_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_directory_creation_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_directory_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_directory_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_directory_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_file_creation_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_file_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_file_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_file_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FileSystemNotifier: Clone + Send + Sync + 'static {
|
|
||||||
fn files_listed(&self, files: &Vec<File>) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn directory_created(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
|
||||||
fn directory_deleted(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn file_created(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
|
||||||
fn file_deleted(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
|
||||||
}
|
|
||||||
@@ -1,2 +1 @@
|
|||||||
pub mod file_system;
|
|
||||||
pub mod warren;
|
pub mod warren;
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use std::{fmt::Display, path::Path};
|
mod requests;
|
||||||
|
pub use requests::*;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use derive_more::Display;
|
use derive_more::Display;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -70,25 +73,20 @@ impl FileName {
|
|||||||
|
|
||||||
Ok(Self(trimmed.to_owned()))
|
Ok(Self(trimmed.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A valid file type
|
/// A valid file type
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Display)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum FileType {
|
pub enum FileType {
|
||||||
File,
|
File,
|
||||||
Directory,
|
Directory,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FileType {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.write_str(match self {
|
|
||||||
Self::File => "File",
|
|
||||||
Self::Directory => "Directory",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A valid file mime type
|
/// A valid file mime type
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
|
||||||
pub struct FileMimeType(String);
|
pub struct FileMimeType(String);
|
||||||
@@ -229,115 +227,3 @@ impl From<AbsoluteFilePath> for FilePath {
|
|||||||
Self(value.0)
|
Self(value.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct ListFilesRequest {
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ListFilesRequest {
|
|
||||||
pub fn new(path: AbsoluteFilePath) -> Self {
|
|
||||||
Self { path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum ListFilesError {
|
|
||||||
#[error("Directory at path {0} does not exist")]
|
|
||||||
NotFound(String),
|
|
||||||
#[error(transparent)]
|
|
||||||
Unknown(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeleteDirectoryRequest {
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct DeleteFileRequest {
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeleteDirectoryRequest {
|
|
||||||
pub fn new(path: AbsoluteFilePath) -> Self {
|
|
||||||
Self { path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeleteFileRequest {
|
|
||||||
pub fn new(path: AbsoluteFilePath) -> Self {
|
|
||||||
Self { path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum DeleteDirectoryError {
|
|
||||||
#[error(transparent)]
|
|
||||||
Unknown(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum DeleteFileError {
|
|
||||||
#[error(transparent)]
|
|
||||||
Unknown(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct CreateDirectoryRequest {
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateDirectoryRequest {
|
|
||||||
pub fn new(path: AbsoluteFilePath) -> Self {
|
|
||||||
Self { path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum CreateDirectoryError {
|
|
||||||
#[error(transparent)]
|
|
||||||
Unknown(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct CreateFileRequest {
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
data: Box<[u8]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreateFileRequest {
|
|
||||||
pub fn new(path: AbsoluteFilePath, data: Box<[u8]>) -> Self {
|
|
||||||
Self { path, data }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn data(&self) -> &[u8] {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum CreateFileError {
|
|
||||||
#[error(transparent)]
|
|
||||||
Unknown(#[from] anyhow::Error),
|
|
||||||
}
|
|
||||||
141
backend/src/lib/domain/warren/models/file/requests.rs
Normal file
141
backend/src/lib/domain/warren/models/file/requests.rs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use super::{AbsoluteFilePath, FileName};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct ListFilesRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListFilesRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath) -> Self {
|
||||||
|
Self { path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ListFilesError {
|
||||||
|
#[error("Directory at path {0} does not exist")]
|
||||||
|
NotFound(String),
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct DeleteDirectoryRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct DeleteFileRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeleteDirectoryRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath) -> Self {
|
||||||
|
Self { path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeleteFileRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath) -> Self {
|
||||||
|
Self { path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DeleteDirectoryError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum DeleteFileError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct CreateDirectoryRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CreateDirectoryRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath) -> Self {
|
||||||
|
Self { path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum CreateDirectoryError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct CreateFileRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
data: Box<[u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CreateFileRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath, data: Box<[u8]>) -> Self {
|
||||||
|
Self { path, data }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> &[u8] {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum CreateFileError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct RenameEntryRequest {
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
new_name: FileName,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenameEntryRequest {
|
||||||
|
pub fn new(path: AbsoluteFilePath, new_name: FileName) -> Self {
|
||||||
|
Self { path, new_name }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_name(&self) -> &FileName {
|
||||||
|
&self.new_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum RenameEntryError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Unknown(#[from] anyhow::Error),
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
|
pub mod file;
|
||||||
pub mod warren;
|
pub mod warren;
|
||||||
|
|||||||
55
backend/src/lib/domain/warren/models/warren/mod.rs
Normal file
55
backend/src/lib/domain/warren/models/warren/mod.rs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
mod requests;
|
||||||
|
use derive_more::Display;
|
||||||
|
pub use requests::*;
|
||||||
|
use thiserror::Error;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::file::AbsoluteFilePath;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::FromRow)]
|
||||||
|
pub struct Warren {
|
||||||
|
id: Uuid,
|
||||||
|
name: WarrenName,
|
||||||
|
path: AbsoluteFilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Warren {
|
||||||
|
pub fn new(id: Uuid, name: WarrenName, path: AbsoluteFilePath) -> Self {
|
||||||
|
Self { id, name, path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> &Uuid {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &WarrenName {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &AbsoluteFilePath {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A valid warren name
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display, sqlx::Type)]
|
||||||
|
#[sqlx(transparent)]
|
||||||
|
pub struct WarrenName(String);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error)]
|
||||||
|
pub enum WarrenNameError {
|
||||||
|
#[error("A warren name must not be empty")]
|
||||||
|
Empty,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WarrenName {
|
||||||
|
pub fn new(raw: &str) -> Result<Self, WarrenNameError> {
|
||||||
|
let trimmed = raw.trim();
|
||||||
|
|
||||||
|
if trimmed.is_empty() {
|
||||||
|
return Err(WarrenNameError::Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self(trimmed.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,60 +1,13 @@
|
|||||||
use derive_more::Display;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::domain::file_system::models::file::{
|
use crate::domain::warren::models::file::{
|
||||||
AbsoluteFilePath, CreateDirectoryError, CreateDirectoryRequest, CreateFileError,
|
AbsoluteFilePath, CreateDirectoryError, CreateDirectoryRequest, CreateFileError,
|
||||||
CreateFileRequest, DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError,
|
CreateFileRequest, DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError,
|
||||||
DeleteFileRequest, FileName, FilePath, ListFilesError, ListFilesRequest, RelativeFilePath,
|
DeleteFileRequest, FileName, FilePath, ListFilesError, ListFilesRequest, RelativeFilePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, sqlx::FromRow)]
|
use super::Warren;
|
||||||
pub struct Warren {
|
|
||||||
id: Uuid,
|
|
||||||
name: WarrenName,
|
|
||||||
path: AbsoluteFilePath,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Warren {
|
|
||||||
pub fn new(id: Uuid, name: WarrenName, path: AbsoluteFilePath) -> Self {
|
|
||||||
Self { id, name, path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> &Uuid {
|
|
||||||
&self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &WarrenName {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(&self) -> &AbsoluteFilePath {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A valid warren name
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display, sqlx::Type)]
|
|
||||||
#[sqlx(transparent)]
|
|
||||||
pub struct WarrenName(String);
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Error)]
|
|
||||||
pub enum WarrenNameError {
|
|
||||||
#[error("A warren name must not be empty")]
|
|
||||||
Empty,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WarrenName {
|
|
||||||
pub fn new(raw: &str) -> Result<Self, WarrenNameError> {
|
|
||||||
let trimmed = raw.trim();
|
|
||||||
|
|
||||||
if trimmed.is_empty() {
|
|
||||||
return Err(WarrenNameError::Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self(trimmed.to_owned()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct FetchWarrenRequest {
|
pub struct FetchWarrenRequest {
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
use crate::domain::file_system::models::file::{File, FilePath};
|
|
||||||
|
|
||||||
use super::models::warren::{
|
|
||||||
CreateWarrenDirectoryError, CreateWarrenDirectoryRequest, DeleteWarrenDirectoryError,
|
|
||||||
DeleteWarrenDirectoryRequest, DeleteWarrenFileError, DeleteWarrenFileRequest, FetchWarrenError,
|
|
||||||
FetchWarrenRequest, ListWarrenFilesError, ListWarrenFilesRequest, ListWarrensError,
|
|
||||||
ListWarrensRequest, UploadWarrenFilesError, UploadWarrenFilesRequest, Warren,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait WarrenService: Clone + Send + Sync + 'static {
|
|
||||||
fn list_warrens(
|
|
||||||
&self,
|
|
||||||
request: ListWarrensRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<Warren>, ListWarrensError>> + Send;
|
|
||||||
|
|
||||||
fn fetch_warren(
|
|
||||||
&self,
|
|
||||||
request: FetchWarrenRequest,
|
|
||||||
) -> impl Future<Output = Result<Warren, FetchWarrenError>> + Send;
|
|
||||||
|
|
||||||
fn list_files(
|
|
||||||
&self,
|
|
||||||
request: ListWarrenFilesRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<File>, ListWarrenFilesError>> + Send;
|
|
||||||
|
|
||||||
fn create_warren_directory(
|
|
||||||
&self,
|
|
||||||
request: CreateWarrenDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, CreateWarrenDirectoryError>> + Send;
|
|
||||||
|
|
||||||
fn delete_warren_directory(
|
|
||||||
&self,
|
|
||||||
request: DeleteWarrenDirectoryRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteWarrenDirectoryError>> + Send;
|
|
||||||
|
|
||||||
fn upload_warren_files(
|
|
||||||
&self,
|
|
||||||
request: UploadWarrenFilesRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<FilePath>, UploadWarrenFilesError>> + Send;
|
|
||||||
fn delete_warren_file(
|
|
||||||
&self,
|
|
||||||
request: DeleteWarrenFileRequest,
|
|
||||||
) -> impl Future<Output = Result<FilePath, DeleteWarrenFileError>> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait WarrenRepository: Clone + Send + Sync + 'static {
|
|
||||||
fn list_warrens(
|
|
||||||
&self,
|
|
||||||
request: ListWarrensRequest,
|
|
||||||
) -> impl Future<Output = Result<Vec<Warren>, ListWarrensError>> + Send;
|
|
||||||
|
|
||||||
fn fetch_warren(
|
|
||||||
&self,
|
|
||||||
request: FetchWarrenRequest,
|
|
||||||
) -> impl Future<Output = Result<Warren, FetchWarrenError>> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait WarrenMetrics: Clone + Send + Sync + 'static {
|
|
||||||
fn record_warren_list_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_warren_list_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_warren_fetch_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_warren_fetch_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_list_warren_files_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_list_warren_files_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_warren_directory_creation_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_warren_directory_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_warren_directory_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_warren_directory_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
/// A single file upload succeeded
|
|
||||||
fn record_warren_file_upload_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
/// A single file upload failed
|
|
||||||
fn record_warren_file_upload_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
/// An upload succeeded fully
|
|
||||||
fn record_warren_files_upload_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
/// An upload failed at least partially
|
|
||||||
fn record_warren_files_upload_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
|
|
||||||
fn record_warren_file_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
fn record_warren_file_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait WarrenNotifier: Clone + Send + Sync + 'static {
|
|
||||||
fn warrens_listed(&self, warrens: &Vec<Warren>) -> impl Future<Output = ()> + Send;
|
|
||||||
fn warren_fetched(&self, warren: &Warren) -> impl Future<Output = ()> + Send;
|
|
||||||
fn warren_files_listed(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
files: &Vec<File>,
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
fn warren_directory_created(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
path: &FilePath,
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
fn warren_directory_deleted(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
path: &FilePath,
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
/// A single file was uploaded
|
|
||||||
///
|
|
||||||
/// * `warren`: The warren the file was uploaded to
|
|
||||||
/// * `path`: The file's path
|
|
||||||
fn warren_file_uploaded(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
path: &FilePath,
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
/// A collection of files was uploaded
|
|
||||||
///
|
|
||||||
/// * `warren`: The warren the file was uploaded to
|
|
||||||
/// * `files`: The files' paths
|
|
||||||
fn warren_files_uploaded(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
files: &[FilePath],
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
fn warren_file_deleted(
|
|
||||||
&self,
|
|
||||||
warren: &Warren,
|
|
||||||
path: &FilePath,
|
|
||||||
) -> impl Future<Output = ()> + Send;
|
|
||||||
}
|
|
||||||
47
backend/src/lib/domain/warren/ports/metrics.rs
Normal file
47
backend/src/lib/domain/warren/ports/metrics.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
pub trait WarrenMetrics: Clone + Send + Sync + 'static {
|
||||||
|
fn record_warren_list_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_warren_list_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_warren_fetch_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_warren_fetch_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_list_warren_files_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_list_warren_files_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_warren_directory_creation_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_warren_directory_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_warren_directory_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_warren_directory_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
/// A single file upload succeeded
|
||||||
|
fn record_warren_file_upload_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
/// A single file upload failed
|
||||||
|
fn record_warren_file_upload_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
/// An upload succeeded fully
|
||||||
|
fn record_warren_files_upload_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
/// An upload failed at least partially
|
||||||
|
fn record_warren_files_upload_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_warren_file_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_warren_file_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FileSystemMetrics: Clone + Send + Sync + 'static {
|
||||||
|
fn record_list_files_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_list_files_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_directory_creation_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_directory_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_directory_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_directory_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_file_creation_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_file_creation_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_file_deletion_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_file_deletion_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn record_entry_rename_success(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
fn record_entry_rename_failure(&self) -> impl Future<Output = ()> + Send;
|
||||||
|
}
|
||||||
88
backend/src/lib/domain/warren/ports/mod.rs
Normal file
88
backend/src/lib/domain/warren/ports/mod.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
mod metrics;
|
||||||
|
mod notifier;
|
||||||
|
mod repository;
|
||||||
|
|
||||||
|
pub use metrics::*;
|
||||||
|
pub use notifier::*;
|
||||||
|
pub use repository::*;
|
||||||
|
|
||||||
|
use super::models::{
|
||||||
|
file::{
|
||||||
|
CreateDirectoryError, CreateDirectoryRequest, CreateFileError, CreateFileRequest,
|
||||||
|
DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError, DeleteFileRequest, File,
|
||||||
|
FilePath, ListFilesError, ListFilesRequest, RenameEntryError, RenameEntryRequest,
|
||||||
|
},
|
||||||
|
warren::{
|
||||||
|
CreateWarrenDirectoryError, CreateWarrenDirectoryRequest, DeleteWarrenDirectoryError,
|
||||||
|
DeleteWarrenDirectoryRequest, DeleteWarrenFileError, DeleteWarrenFileRequest,
|
||||||
|
FetchWarrenError, FetchWarrenRequest, ListWarrenFilesError, ListWarrenFilesRequest,
|
||||||
|
ListWarrensError, ListWarrensRequest, UploadWarrenFilesError, UploadWarrenFilesRequest,
|
||||||
|
Warren,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait WarrenService: Clone + Send + Sync + 'static {
|
||||||
|
fn list_warrens(
|
||||||
|
&self,
|
||||||
|
request: ListWarrensRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<Warren>, ListWarrensError>> + Send;
|
||||||
|
|
||||||
|
fn fetch_warren(
|
||||||
|
&self,
|
||||||
|
request: FetchWarrenRequest,
|
||||||
|
) -> impl Future<Output = Result<Warren, FetchWarrenError>> + Send;
|
||||||
|
|
||||||
|
fn list_files(
|
||||||
|
&self,
|
||||||
|
request: ListWarrenFilesRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<File>, ListWarrenFilesError>> + Send;
|
||||||
|
|
||||||
|
fn create_warren_directory(
|
||||||
|
&self,
|
||||||
|
request: CreateWarrenDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, CreateWarrenDirectoryError>> + Send;
|
||||||
|
|
||||||
|
fn delete_warren_directory(
|
||||||
|
&self,
|
||||||
|
request: DeleteWarrenDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteWarrenDirectoryError>> + Send;
|
||||||
|
|
||||||
|
fn upload_warren_files(
|
||||||
|
&self,
|
||||||
|
request: UploadWarrenFilesRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<FilePath>, UploadWarrenFilesError>> + Send;
|
||||||
|
fn delete_warren_file(
|
||||||
|
&self,
|
||||||
|
request: DeleteWarrenFileRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteWarrenFileError>> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FileSystemService: Clone + Send + Sync + 'static {
|
||||||
|
fn list_files(
|
||||||
|
&self,
|
||||||
|
request: ListFilesRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<File>, ListFilesError>> + Send;
|
||||||
|
|
||||||
|
fn create_directory(
|
||||||
|
&self,
|
||||||
|
request: CreateDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, CreateDirectoryError>> + Send;
|
||||||
|
fn delete_directory(
|
||||||
|
&self,
|
||||||
|
request: DeleteDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteDirectoryError>> + Send;
|
||||||
|
|
||||||
|
fn create_file(
|
||||||
|
&self,
|
||||||
|
request: CreateFileRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, CreateFileError>> + Send;
|
||||||
|
fn delete_file(
|
||||||
|
&self,
|
||||||
|
request: DeleteFileRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteFileError>> + Send;
|
||||||
|
|
||||||
|
fn rename_entry(
|
||||||
|
&self,
|
||||||
|
request: RenameEntryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, RenameEntryError>> + Send;
|
||||||
|
}
|
||||||
63
backend/src/lib/domain/warren/ports/notifier.rs
Normal file
63
backend/src/lib/domain/warren/ports/notifier.rs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
use crate::domain::warren::models::{
|
||||||
|
file::{File, FilePath},
|
||||||
|
warren::Warren,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait WarrenNotifier: Clone + Send + Sync + 'static {
|
||||||
|
fn warrens_listed(&self, warrens: &Vec<Warren>) -> impl Future<Output = ()> + Send;
|
||||||
|
fn warren_fetched(&self, warren: &Warren) -> impl Future<Output = ()> + Send;
|
||||||
|
fn warren_files_listed(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
files: &Vec<File>,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
fn warren_directory_created(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
path: &FilePath,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
fn warren_directory_deleted(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
path: &FilePath,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
/// A single file was uploaded
|
||||||
|
///
|
||||||
|
/// * `warren`: The warren the file was uploaded to
|
||||||
|
/// * `path`: The file's path
|
||||||
|
fn warren_file_uploaded(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
path: &FilePath,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
/// A collection of files was uploaded
|
||||||
|
///
|
||||||
|
/// * `warren`: The warren the file was uploaded to
|
||||||
|
/// * `files`: The files' paths
|
||||||
|
fn warren_files_uploaded(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
files: &[FilePath],
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
fn warren_file_deleted(
|
||||||
|
&self,
|
||||||
|
warren: &Warren,
|
||||||
|
path: &FilePath,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FileSystemNotifier: Clone + Send + Sync + 'static {
|
||||||
|
fn files_listed(&self, files: &Vec<File>) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn directory_created(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
||||||
|
fn directory_deleted(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn file_created(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
||||||
|
fn file_deleted(&self, path: &FilePath) -> impl Future<Output = ()> + Send;
|
||||||
|
|
||||||
|
fn entry_renamed(
|
||||||
|
&self,
|
||||||
|
old_path: &FilePath,
|
||||||
|
new_path: &FilePath,
|
||||||
|
) -> impl Future<Output = ()> + Send;
|
||||||
|
}
|
||||||
50
backend/src/lib/domain/warren/ports/repository.rs
Normal file
50
backend/src/lib/domain/warren/ports/repository.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use crate::domain::warren::models::{
|
||||||
|
file::{
|
||||||
|
CreateDirectoryError, CreateDirectoryRequest, CreateFileError, CreateFileRequest,
|
||||||
|
DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError, DeleteFileRequest, File,
|
||||||
|
FilePath, ListFilesError, ListFilesRequest, RenameEntryError, RenameEntryRequest,
|
||||||
|
},
|
||||||
|
warren::{FetchWarrenError, FetchWarrenRequest, ListWarrensError, ListWarrensRequest, Warren},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait WarrenRepository: Clone + Send + Sync + 'static {
|
||||||
|
fn list_warrens(
|
||||||
|
&self,
|
||||||
|
request: ListWarrensRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<Warren>, ListWarrensError>> + Send;
|
||||||
|
|
||||||
|
fn fetch_warren(
|
||||||
|
&self,
|
||||||
|
request: FetchWarrenRequest,
|
||||||
|
) -> impl Future<Output = Result<Warren, FetchWarrenError>> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FileSystemRepository: Clone + Send + Sync + 'static {
|
||||||
|
fn list_files(
|
||||||
|
&self,
|
||||||
|
request: ListFilesRequest,
|
||||||
|
) -> impl Future<Output = Result<Vec<File>, ListFilesError>> + Send;
|
||||||
|
|
||||||
|
fn create_directory(
|
||||||
|
&self,
|
||||||
|
request: CreateDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, CreateDirectoryError>> + Send;
|
||||||
|
fn delete_directory(
|
||||||
|
&self,
|
||||||
|
request: DeleteDirectoryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteDirectoryError>> + Send;
|
||||||
|
|
||||||
|
fn create_file(
|
||||||
|
&self,
|
||||||
|
request: CreateFileRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, CreateFileError>> + Send;
|
||||||
|
fn delete_file(
|
||||||
|
&self,
|
||||||
|
request: DeleteFileRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, DeleteFileError>> + Send;
|
||||||
|
|
||||||
|
fn rename_entry(
|
||||||
|
&self,
|
||||||
|
request: RenameEntryRequest,
|
||||||
|
) -> impl Future<Output = Result<FilePath, RenameEntryError>> + Send;
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
use super::{
|
use crate::domain::warren::{
|
||||||
models::file::{
|
models::file::{
|
||||||
CreateDirectoryError, CreateDirectoryRequest, CreateFileError, CreateFileRequest,
|
CreateDirectoryError, CreateDirectoryRequest, CreateFileError, CreateFileRequest,
|
||||||
DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError, DeleteFileRequest, FilePath,
|
DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError, DeleteFileRequest, File,
|
||||||
ListFilesError, ListFilesRequest,
|
FilePath, ListFilesError, ListFilesRequest, RenameEntryError, RenameEntryRequest,
|
||||||
},
|
},
|
||||||
ports::{FileSystemMetrics, FileSystemNotifier, FileSystemRepository, FileSystemService},
|
ports::{FileSystemMetrics, FileSystemNotifier, FileSystemRepository, FileSystemService},
|
||||||
};
|
};
|
||||||
@@ -40,10 +40,7 @@ where
|
|||||||
M: FileSystemMetrics,
|
M: FileSystemMetrics,
|
||||||
N: FileSystemNotifier,
|
N: FileSystemNotifier,
|
||||||
{
|
{
|
||||||
async fn list_files(
|
async fn list_files(&self, request: ListFilesRequest) -> Result<Vec<File>, ListFilesError> {
|
||||||
&self,
|
|
||||||
request: ListFilesRequest,
|
|
||||||
) -> Result<Vec<super::models::file::File>, ListFilesError> {
|
|
||||||
let result = self.repository.list_files(request).await;
|
let result = self.repository.list_files(request).await;
|
||||||
|
|
||||||
if let Ok(files) = result.as_ref() {
|
if let Ok(files) = result.as_ref() {
|
||||||
@@ -113,4 +110,21 @@ where
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn rename_entry(
|
||||||
|
&self,
|
||||||
|
request: RenameEntryRequest,
|
||||||
|
) -> Result<FilePath, RenameEntryError> {
|
||||||
|
let old_path = request.path().clone();
|
||||||
|
let result = self.repository.rename_entry(request).await;
|
||||||
|
|
||||||
|
if let Ok(path) = result.as_ref() {
|
||||||
|
self.metrics.record_entry_rename_success().await;
|
||||||
|
self.notifier.entry_renamed(&old_path.into(), path).await;
|
||||||
|
} else {
|
||||||
|
self.metrics.record_entry_rename_failure().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
2
backend/src/lib/domain/warren/service/mod.rs
Normal file
2
backend/src/lib/domain/warren/service/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod file_system;
|
||||||
|
pub mod warren;
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
||||||
use crate::domain::file_system::{
|
use crate::domain::warren::{
|
||||||
models::file::{File, FilePath},
|
models::{
|
||||||
|
file::{File, FilePath},
|
||||||
|
warren::{ListWarrensError, ListWarrensRequest},
|
||||||
|
},
|
||||||
ports::FileSystemService,
|
ports::FileSystemService,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
models::warren::{
|
super::models::warren::{
|
||||||
CreateWarrenDirectoryError, CreateWarrenDirectoryRequest, DeleteWarrenDirectoryError,
|
CreateWarrenDirectoryError, CreateWarrenDirectoryRequest, DeleteWarrenDirectoryError,
|
||||||
DeleteWarrenDirectoryRequest, DeleteWarrenFileError, DeleteWarrenFileRequest,
|
DeleteWarrenDirectoryRequest, DeleteWarrenFileError, DeleteWarrenFileRequest,
|
||||||
FetchWarrenError, FetchWarrenRequest, ListWarrenFilesError, ListWarrenFilesRequest,
|
FetchWarrenError, FetchWarrenRequest, ListWarrenFilesError, ListWarrenFilesRequest,
|
||||||
UploadWarrenFilesError, UploadWarrenFilesRequest, Warren,
|
UploadWarrenFilesError, UploadWarrenFilesRequest, Warren,
|
||||||
},
|
},
|
||||||
ports::{WarrenMetrics, WarrenNotifier, WarrenRepository, WarrenService},
|
super::ports::{WarrenMetrics, WarrenNotifier, WarrenRepository, WarrenService},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -55,8 +58,8 @@ where
|
|||||||
{
|
{
|
||||||
async fn list_warrens(
|
async fn list_warrens(
|
||||||
&self,
|
&self,
|
||||||
request: super::models::warren::ListWarrensRequest,
|
request: ListWarrensRequest,
|
||||||
) -> Result<Vec<Warren>, super::models::warren::ListWarrensError> {
|
) -> Result<Vec<Warren>, ListWarrensError> {
|
||||||
let result = self.repository.list_warrens(request).await;
|
let result = self.repository.list_warrens(request).await;
|
||||||
|
|
||||||
if let Ok(warren) = result.as_ref() {
|
if let Ok(warren) = result.as_ref() {
|
||||||
@@ -4,12 +4,12 @@ use thiserror::Error;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::warren::{
|
||||||
file_system::models::file::{AbsoluteFilePathError, FilePath, FilePathError},
|
models::{
|
||||||
warren::{
|
file::{AbsoluteFilePathError, FilePath, FilePathError},
|
||||||
models::warren::{CreateWarrenDirectoryError, CreateWarrenDirectoryRequest},
|
warren::{CreateWarrenDirectoryError, CreateWarrenDirectoryRequest},
|
||||||
ports::WarrenService,
|
|
||||||
},
|
},
|
||||||
|
ports::WarrenService,
|
||||||
},
|
},
|
||||||
inbound::http::{
|
inbound::http::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ use thiserror::Error;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::warren::{
|
||||||
file_system::models::file::{AbsoluteFilePathError, FilePath, FilePathError},
|
models::{
|
||||||
warren::{
|
file::{AbsoluteFilePathError, FilePath, FilePathError},
|
||||||
models::warren::{DeleteWarrenDirectoryError, DeleteWarrenDirectoryRequest},
|
warren::{DeleteWarrenDirectoryError, DeleteWarrenDirectoryRequest},
|
||||||
ports::WarrenService,
|
|
||||||
},
|
},
|
||||||
|
ports::WarrenService,
|
||||||
},
|
},
|
||||||
inbound::http::{
|
inbound::http::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ use thiserror::Error;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::warren::{
|
||||||
file_system::models::file::{AbsoluteFilePathError, FilePath, FilePathError},
|
models::{
|
||||||
warren::{
|
file::{AbsoluteFilePathError, FilePath, FilePathError},
|
||||||
models::warren::{DeleteWarrenFileError, DeleteWarrenFileRequest},
|
warren::{DeleteWarrenFileError, DeleteWarrenFileRequest},
|
||||||
ports::WarrenService,
|
|
||||||
},
|
},
|
||||||
|
ports::WarrenService,
|
||||||
},
|
},
|
||||||
inbound::http::{
|
inbound::http::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|||||||
@@ -4,14 +4,12 @@ use thiserror::Error;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::warren::{
|
||||||
file_system::models::file::{
|
models::{
|
||||||
AbsoluteFilePathError, File, FileMimeType, FilePath, FilePathError, FileType,
|
file::{AbsoluteFilePathError, File, FileMimeType, FilePath, FilePathError, FileType},
|
||||||
},
|
warren::{ListWarrenFilesError, ListWarrenFilesRequest},
|
||||||
warren::{
|
|
||||||
models::warren::{ListWarrenFilesError, ListWarrenFilesRequest},
|
|
||||||
ports::WarrenService,
|
|
||||||
},
|
},
|
||||||
|
ports::WarrenService,
|
||||||
},
|
},
|
||||||
inbound::http::{
|
inbound::http::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|||||||
@@ -4,17 +4,15 @@ use thiserror::Error;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
domain::{
|
domain::warren::{
|
||||||
file_system::models::file::{
|
models::{
|
||||||
AbsoluteFilePathError, FileName, FileNameError, FilePath, FilePathError,
|
file::{AbsoluteFilePathError, FileName, FileNameError, FilePath, FilePathError},
|
||||||
},
|
warren::{
|
||||||
warren::{
|
|
||||||
models::warren::{
|
|
||||||
UploadFile, UploadFileList, UploadFileListError, UploadWarrenFilesError,
|
UploadFile, UploadFileList, UploadFileListError, UploadWarrenFilesError,
|
||||||
UploadWarrenFilesRequest,
|
UploadWarrenFilesRequest,
|
||||||
},
|
},
|
||||||
ports::WarrenService,
|
|
||||||
},
|
},
|
||||||
|
ports::WarrenService,
|
||||||
},
|
},
|
||||||
inbound::http::{
|
inbound::http::{
|
||||||
AppState,
|
AppState,
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ use std::time::UNIX_EPOCH;
|
|||||||
use anyhow::{Context, anyhow};
|
use anyhow::{Context, anyhow};
|
||||||
use tokio::{fs, io::AsyncWriteExt as _};
|
use tokio::{fs, io::AsyncWriteExt as _};
|
||||||
|
|
||||||
use crate::domain::file_system::{
|
use crate::domain::warren::{
|
||||||
models::file::{
|
models::file::{
|
||||||
AbsoluteFilePath, CreateDirectoryError, CreateDirectoryRequest, CreateFileError,
|
AbsoluteFilePath, CreateDirectoryError, CreateDirectoryRequest, CreateFileError,
|
||||||
CreateFileRequest, DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError,
|
CreateFileRequest, DeleteDirectoryError, DeleteDirectoryRequest, DeleteFileError,
|
||||||
DeleteFileRequest, File, FileMimeType, FileName, FilePath, FileType, ListFilesError,
|
DeleteFileRequest, File, FileMimeType, FileName, FilePath, FileType, ListFilesError,
|
||||||
ListFilesRequest,
|
ListFilesRequest, RenameEntryError, RenameEntryRequest,
|
||||||
},
|
},
|
||||||
ports::FileSystemRepository,
|
ports::FileSystemRepository,
|
||||||
};
|
};
|
||||||
@@ -139,6 +139,27 @@ impl FileSystem {
|
|||||||
|
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn rename(
|
||||||
|
&self,
|
||||||
|
path: &AbsoluteFilePath,
|
||||||
|
new_name: &FileName,
|
||||||
|
) -> anyhow::Result<FilePath> {
|
||||||
|
let current_path = self.get_target_path(path);
|
||||||
|
|
||||||
|
let new_path = {
|
||||||
|
let mut c = current_path.to_string();
|
||||||
|
let last_slash_index = c.rfind('/').unwrap();
|
||||||
|
c.drain((last_slash_index + 1)..);
|
||||||
|
c.push_str(new_name.as_str());
|
||||||
|
|
||||||
|
FilePath::new(&c)?
|
||||||
|
};
|
||||||
|
|
||||||
|
fs::rename(current_path, &new_path).await?;
|
||||||
|
|
||||||
|
Ok(new_path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileSystemRepository for FileSystem {
|
impl FileSystemRepository for FileSystem {
|
||||||
@@ -198,4 +219,20 @@ impl FileSystemRepository for FileSystem {
|
|||||||
|
|
||||||
Ok(deleted_path)
|
Ok(deleted_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn rename_entry(
|
||||||
|
&self,
|
||||||
|
request: RenameEntryRequest,
|
||||||
|
) -> Result<FilePath, RenameEntryError> {
|
||||||
|
let new_path = self
|
||||||
|
.rename(request.path(), request.new_name())
|
||||||
|
.await
|
||||||
|
.context(format!(
|
||||||
|
"Failed to rename {} to {}",
|
||||||
|
request.path(),
|
||||||
|
request.new_name()
|
||||||
|
))?;
|
||||||
|
|
||||||
|
Ok(new_path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::domain::{file_system::ports::FileSystemMetrics, warren::ports::WarrenMetrics};
|
use crate::domain::warren::ports::{FileSystemMetrics, WarrenMetrics};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct MetricsDebugLogger;
|
pub struct MetricsDebugLogger;
|
||||||
@@ -107,4 +107,11 @@ impl FileSystemMetrics for MetricsDebugLogger {
|
|||||||
async fn record_file_deletion_failure(&self) {
|
async fn record_file_deletion_failure(&self) {
|
||||||
log::debug!("[Metrics] File deletion failed");
|
log::debug!("[Metrics] File deletion failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn record_entry_rename_success(&self) -> () {
|
||||||
|
log::debug!("[Metrics] Entry rename succeeded");
|
||||||
|
}
|
||||||
|
async fn record_entry_rename_failure(&self) -> () {
|
||||||
|
log::debug!("[Metrics] Entry rename failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::domain::{
|
use crate::domain::warren::{
|
||||||
file_system::{
|
models::{
|
||||||
models::file::{File, FilePath},
|
file::{File, FilePath},
|
||||||
ports::FileSystemNotifier,
|
warren::Warren,
|
||||||
},
|
},
|
||||||
warren::{models::warren::Warren, ports::WarrenNotifier},
|
ports::{FileSystemNotifier, WarrenNotifier},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -93,4 +93,8 @@ impl FileSystemNotifier for NotifierDebugLogger {
|
|||||||
async fn file_deleted(&self, path: &FilePath) {
|
async fn file_deleted(&self, path: &FilePath) {
|
||||||
log::debug!("[Notifier] Deleted file {}", path);
|
log::debug!("[Notifier] Deleted file {}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn entry_renamed(&self, old_path: &FilePath, new_path: &FilePath) {
|
||||||
|
log::debug!("[Notifier] Renamed file {} to {}", old_path, new_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user