summaryrefslogtreecommitdiff
path: root/systems/vault
diff options
context:
space:
mode:
Diffstat (limited to 'systems/vault')
-rw-r--r--systems/vault/Cargo.toml14
-rw-r--r--systems/vault/src/func.rs40
-rw-r--r--systems/vault/src/lib.rs2
-rw-r--r--systems/vault/src/vault.rs41
-rw-r--r--systems/vault/src/vault/config.rs45
-rw-r--r--systems/vault/src/vault/error.rs40
-rw-r--r--systems/vault/src/vault/manager.rs37
7 files changed, 219 insertions, 0 deletions
diff --git a/systems/vault/Cargo.toml b/systems/vault/Cargo.toml
new file mode 100644
index 0000000..d0cfe7f
--- /dev/null
+++ b/systems/vault/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "vault_system"
+edition = "2024"
+version.workspace = true
+
+[dependencies]
+asset_system = { path = "../_asset" }
+config_system = { path = "../_config" }
+constants = { path = "../_constants" }
+framework = { path = "../_framework" }
+
+serde.workspace = true
+thiserror.workspace = true
+tokio.workspace = true
diff --git a/systems/vault/src/func.rs b/systems/vault/src/func.rs
new file mode 100644
index 0000000..125c0ac
--- /dev/null
+++ b/systems/vault/src/func.rs
@@ -0,0 +1,40 @@
+use crate::vault::{Vault, config::VaultConfig, error::VaultOperationError, manager::VaultManager};
+use asset_system::asset::Handle;
+use framework::space::Space;
+use std::{env::current_dir, path::PathBuf};
+
+/// Create a vault at the current location
+pub async fn create_vault_here() -> Result<(), VaultOperationError> {
+ create_vault(current_dir()?).await
+}
+
+/// Create a vault at the specified location
+pub async fn create_vault(path: impl Into<PathBuf>) -> Result<(), VaultOperationError> {
+ let path = path.into();
+ let mut space = Space::new(Vault);
+ space.set_current_dir(path)?;
+ space.init_here().await?;
+
+ Ok(())
+}
+
+#[allow(unused)]
+/// Get a handle to the vault configuration file and edit its content
+pub async fn operate_vault_config<F>(
+ vault_path: impl Into<PathBuf>,
+ operate: F,
+) -> Result<(), VaultOperationError>
+where
+ F: AsyncFn(Handle<VaultConfig>),
+{
+ // Get the vault manager and set the context to the given vault path
+ let mut mgr = VaultManager::new();
+ mgr.get_space_mut().set_current_dir(vault_path.into())?;
+
+ // Obtain the vault configuration, and pass it to the function for execution
+ let config = mgr.vault_config()?;
+ let handle = config.get_handle().await?;
+ operate(handle).await;
+
+ Ok(())
+}
diff --git a/systems/vault/src/lib.rs b/systems/vault/src/lib.rs
new file mode 100644
index 0000000..c64eae4
--- /dev/null
+++ b/systems/vault/src/lib.rs
@@ -0,0 +1,2 @@
+pub mod func;
+pub mod vault;
diff --git a/systems/vault/src/vault.rs b/systems/vault/src/vault.rs
new file mode 100644
index 0000000..262f8c5
--- /dev/null
+++ b/systems/vault/src/vault.rs
@@ -0,0 +1,41 @@
+use asset_system::rw::RWData;
+use constants::vault::{
+ dirs::{vault_dir_changes, vault_dir_ignore_rules, vault_dir_member_root, vault_dir_refsheets},
+ files::vault_file_config,
+};
+use framework::{SpaceRootTest, space::SpaceRoot};
+use tokio::fs;
+
+use crate::vault::config::VaultConfig;
+
+pub mod config;
+pub mod error;
+pub mod manager;
+
+#[derive(Default, SpaceRootTest)]
+pub struct Vault;
+
+impl SpaceRoot for Vault {
+ fn get_pattern() -> framework::space::SpaceRootFindPattern {
+ framework::space::SpaceRootFindPattern::IncludeFile(vault_file_config().into())
+ }
+
+ async fn create_space(
+ path: &std::path::Path,
+ ) -> Result<(), framework::space::error::SpaceError> {
+ let vault_toml = path.join(vault_file_config());
+
+ // Create configuration file
+ VaultConfig::write(VaultConfig::default(), &vault_toml)
+ .await
+ .map_err(|e| framework::space::error::SpaceError::Other(e.to_string()))?;
+
+ // Create directories
+ fs::create_dir_all(vault_dir_refsheets()).await?;
+ fs::create_dir_all(vault_dir_member_root()).await?;
+ fs::create_dir_all(vault_dir_ignore_rules()).await?;
+ fs::create_dir_all(vault_dir_changes()).await?;
+
+ Ok(())
+ }
+}
diff --git a/systems/vault/src/vault/config.rs b/systems/vault/src/vault/config.rs
new file mode 100644
index 0000000..7c4db70
--- /dev/null
+++ b/systems/vault/src/vault/config.rs
@@ -0,0 +1,45 @@
+use asset_system::{RWDataTest, rw::RWData};
+use config_system::rw::{read_config, write_config};
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, RWDataTest)]
+pub struct VaultConfig {}
+
+impl RWData<VaultConfig> for VaultConfig {
+ type DataType = VaultConfig;
+
+ async fn read(
+ path: &std::path::PathBuf,
+ ) -> Result<Self::DataType, asset_system::error::DataReadError> {
+ let read_config = read_config(path).await;
+ match read_config {
+ Ok(config) => Ok(config),
+ Err(e) => Err(asset_system::error::DataReadError::IoError(
+ std::io::Error::new(std::io::ErrorKind::Other, e),
+ )),
+ }
+ }
+
+ async fn write(
+ data: Self::DataType,
+ path: &std::path::PathBuf,
+ ) -> Result<(), asset_system::error::DataWriteError> {
+ let write_config = write_config(path, &data).await;
+ match write_config {
+ Ok(_) => Ok(()),
+ Err(e) => {
+ return Err(asset_system::error::DataWriteError::IoError(
+ std::io::Error::new(std::io::ErrorKind::Other, e),
+ ));
+ }
+ }
+ }
+
+ fn test_data() -> Self::DataType {
+ VaultConfig::default()
+ }
+
+ fn verify_data(data_a: Self::DataType, data_b: Self::DataType) -> bool {
+ &data_a == &data_b
+ }
+}
diff --git a/systems/vault/src/vault/error.rs b/systems/vault/src/vault/error.rs
new file mode 100644
index 0000000..b35a9c8
--- /dev/null
+++ b/systems/vault/src/vault/error.rs
@@ -0,0 +1,40 @@
+use asset_system::error::{DataApplyError, DataReadError, DataWriteError, HandleLockError};
+use framework::space::error::SpaceError;
+
+#[derive(thiserror::Error, Debug)]
+pub enum VaultOperationError {
+ #[error("IO error: {0}")]
+ Io(#[from] std::io::Error),
+
+ #[error("{0}")]
+ Other(String),
+
+ #[error("Configuration not found")]
+ ConfigNotFound,
+
+ #[error("Vault not found")]
+ VaultNotFound,
+
+ #[error("Handle lock error: {0}")]
+ HandleLock(#[from] HandleLockError),
+
+ #[error("Data read error: {0}")]
+ DataRead(#[from] DataReadError),
+
+ #[error("Data write error: {0}")]
+ DataWrite(#[from] DataWriteError),
+
+ #[error("Data apply error: {0}")]
+ DataApply(#[from] DataApplyError),
+}
+
+impl From<SpaceError> for VaultOperationError {
+ fn from(value: SpaceError) -> Self {
+ match value {
+ SpaceError::SpaceNotFound => VaultOperationError::VaultNotFound,
+ SpaceError::Io(error) => VaultOperationError::Io(error),
+ SpaceError::Other(e) => Self::Other(e),
+ _ => Self::Other(value.to_string()),
+ }
+ }
+}
diff --git a/systems/vault/src/vault/manager.rs b/systems/vault/src/vault/manager.rs
new file mode 100644
index 0000000..bae26d4
--- /dev/null
+++ b/systems/vault/src/vault/manager.rs
@@ -0,0 +1,37 @@
+use asset_system::asset::ReadOnlyAsset;
+use constants::vault::files::vault_file_config;
+use framework::space::Space;
+
+use crate::vault::{Vault, config::VaultConfig, error::VaultOperationError};
+
+pub struct VaultManager {
+ space: Space<Vault>,
+}
+
+impl VaultManager {
+ pub fn new() -> Self {
+ VaultManager {
+ space: Space::new(Vault),
+ }
+ }
+
+ /// Get an immutable reference to the internal Space
+ pub fn get_space(&self) -> &Space<Vault> {
+ &self.space
+ }
+
+ /// Get a mutable reference to the internal Space
+ pub fn get_space_mut(&mut self) -> &mut Space<Vault> {
+ &mut self.space
+ }
+
+ /// Get a read-only instance of the vault configuration file
+ pub fn vault_config(&self) -> Result<ReadOnlyAsset<VaultConfig>, VaultOperationError> {
+ let config_path = self.space.local_path(vault_file_config())?;
+ if !config_path.exists() {
+ return Err(VaultOperationError::ConfigNotFound);
+ }
+ let asset = ReadOnlyAsset::from(config_path);
+ Ok(asset)
+ }
+}