summaryrefslogtreecommitdiff
path: root/systems
diff options
context:
space:
mode:
Diffstat (limited to 'systems')
-rw-r--r--systems/_constants/src/lib.rs33
-rw-r--r--systems/workspace/Cargo.toml1
-rw-r--r--systems/workspace/src/workspace/manager.rs1
-rw-r--r--systems/workspace/src/workspace/manager/sheet_state.rs73
4 files changed, 98 insertions, 10 deletions
diff --git a/systems/_constants/src/lib.rs b/systems/_constants/src/lib.rs
index b9d313c..e576be3 100644
--- a/systems/_constants/src/lib.rs
+++ b/systems/_constants/src/lib.rs
@@ -14,7 +14,7 @@ pub mod server {
/// File constants
#[constants_macros::constants("server_file")]
pub mod files {
- c! { CONFIG = "config.toml" }
+ c! { CONFIG = "server.toml" }
// Storage location for keys and passwords
c! { KEY = "auth/key/{member_name}.pem" }
@@ -114,10 +114,13 @@ pub mod workspace {
// ### Sheets ###
// Records the latest state of local physical files, used to calculate deviations
- c! { LOCAL_STATUS = ".jv/sheets/{account}/{sheet}.local" }
+ c! { LOCAL_STATUS = ".jv/sheets/{sheet}.local" }
// Personal sheet, represents the desired file structure, held only by the member, can be backed up to the vault
- c! { SHEET = ".jv/sheets/{account}/{sheet}.sheet" }
+ c! { SHEET = ".jv/sheets/{sheet}.sheet" }
+
+ // Current sheet name
+ c! { CURRENT_SHEET = ".jv/sheets/CURRENT" }
// Draft file, when switching to another sheet, fully records modified but untracked files
c! { DRAFTED_FILE = ".jv/drafts/{account}_{sheet}/{mapping}" }
@@ -131,7 +134,7 @@ pub mod workspace {
pub mod dirs {
c! { WORKSPACE = ".jv" }
c! { VAULT_MIRROR = ".jv/UPSTREAM/" }
- c! { LOCAL_SHEETS = ".jv/sheets/{account}/" }
+ c! { LOCAL_SHEETS = ".jv/sheets/" }
c! { DRAFT_AREA = ".jv/drafts/{account}_{sheet}/" }
c! { ID_MAPPING = ".jv/idmp/" }
c! { WORKING_AREA = "" }
@@ -141,26 +144,36 @@ pub mod workspace {
/// File and directory path constants for the user root
#[allow(unused)]
pub mod user {
+ /// Others
+ #[constants_macros::constants("user_value")]
+ pub mod values {
+ c! { USER_CONFIG_NAME = "usr.toml" }
+ }
+
/// File path constants
#[constants_macros::constants("user_file")]
pub mod files {
// Upstream public key, stored after initial login, used to verify the trustworthiness of that upstream
- c! { UPSTREAM_PUB = "upstreams/{upstream_addr}.pem" }
+ c! { JVCS_UPSTREAM_PUB = ".jvcs/upstreams/{jvcs_upstream_addr}.pem" }
// Account private key, stored only locally, used for login authentication
- c! { PRIVATE_KEY = "private/{account}.pem" }
+ c! { PRIVATE_KEY = ".jvcs/private/{account}.pem" }
// Account public key, automatically generated from the private key and stored,
// will be placed into the server's "join request list" upon initial login (if server.toml permits this action)
// The server administrator can optionally approve this request
- c! { PUBLIC_KEY = "public/{account}.pem" }
+ c! { PUBLIC_KEY = ".jvcs/public/{account}.pem" }
+
+ // Account configuration file
+ c! { USER_CONFIG = ".jvcs/usr.toml" }
}
/// Directory path constants
#[constants_macros::constants("user_dir")]
pub mod dirs {
- c! { UPSTREAM_PUBS = "upstreams/" }
- c! { PRIVATE_KEYS = "private/" }
- c! { PUBLIC_KEYS = "public/" }
+ c! { ROOT = ".jvcs/" }
+ c! { UPSTREAM_PUBS = ".jvcs/upstreams/" }
+ c! { PRIVATE_KEYS = ".jvcs/private/" }
+ c! { PUBLIC_KEYS = ".jvcs/public/" }
}
}
diff --git a/systems/workspace/Cargo.toml b/systems/workspace/Cargo.toml
index c601370..90690f8 100644
--- a/systems/workspace/Cargo.toml
+++ b/systems/workspace/Cargo.toml
@@ -10,6 +10,7 @@ constants = { path = "../_constants" }
framework = { path = "../_framework" }
sheet_system = { path = "../sheet" }
+just_fmt.workspace = true
serde.workspace = true
thiserror.workspace = true
tokio.workspace = true
diff --git a/systems/workspace/src/workspace/manager.rs b/systems/workspace/src/workspace/manager.rs
index adee9b7..58eb409 100644
--- a/systems/workspace/src/workspace/manager.rs
+++ b/systems/workspace/src/workspace/manager.rs
@@ -4,6 +4,7 @@ use constants::workspace::files::workspace_file_config;
use framework::space::Space;
pub mod id_aliases;
+pub mod sheet_state;
pub struct WorkspaceManager {
space: Space<Workspace>,
diff --git a/systems/workspace/src/workspace/manager/sheet_state.rs b/systems/workspace/src/workspace/manager/sheet_state.rs
new file mode 100644
index 0000000..5603adf
--- /dev/null
+++ b/systems/workspace/src/workspace/manager/sheet_state.rs
@@ -0,0 +1,73 @@
+use std::path::PathBuf;
+
+use crate::workspace::manager::WorkspaceManager;
+use asset_system::asset::ReadOnlyAsset;
+use constants::workspace::files::{workspace_file_current_sheet, workspace_file_sheet};
+use framework::space::error::SpaceError;
+use just_fmt::snake_case;
+use sheet_system::sheet::{Sheet, SheetData};
+
+impl WorkspaceManager {
+ /// Read the name of the currently active Sheet
+ pub async fn using_sheet_name(&self) -> Result<Option<String>, SpaceError> {
+ match self
+ .space
+ .read_to_string(workspace_file_current_sheet())
+ .await
+ {
+ Ok(s) => Ok(Some(s.trim().to_string())),
+ Err(SpaceError::Io(io_error)) => match io_error.kind() {
+ std::io::ErrorKind::NotFound => Ok(None),
+ _ => Err(SpaceError::Io(io_error)),
+ },
+ Err(e) => Err(e),
+ }
+ }
+
+ /// Set the name of the currently active Sheet
+ pub async fn edit_using_sheet_name(&self, name: &str) -> Result<(), SpaceError> {
+ self.space
+ .write(workspace_file_current_sheet(), name.as_bytes())
+ .await
+ }
+
+ /// Read a sheet from the workspace space by name
+ ///
+ /// Simple read of Sheet data, no disk write operations involved
+ pub async fn read_sheet(&self, sheet_name: &str) -> Option<Sheet> {
+ let sheet_name = snake_case!(sheet_name);
+ let sheet_path = self.get_sheet_path(&sheet_name);
+
+ let mut sheet_data = SheetData::empty();
+ if sheet_path.exists() {
+ // If reading fails, treat it as if the sheet does not exist and return `None`
+ sheet_data.full_read(sheet_path).await.ok()?;
+ return Some(sheet_data.pack(sheet_name));
+ } else {
+ None
+ }
+ }
+
+ /// Get a resource pointing to local Sheet data by name
+ ///
+ /// Can be used to load content, edit, and transactionally write
+ pub fn get_sheet_data_asset(&self, sheet_name: &str) -> Option<ReadOnlyAsset<SheetData>> {
+ let sheet_name = snake_case!(sheet_name);
+ let sheet_path = self.get_sheet_path(&sheet_name);
+ if sheet_path.exists() {
+ return Some(sheet_path.into());
+ }
+ None
+ }
+
+ /// Get the local filesystem path for a sheet by name
+ pub fn get_sheet_path(&self, sheet_name: impl AsRef<str>) -> PathBuf {
+ let sheet_name = sheet_name.as_ref();
+ self.space
+ .local_path(workspace_file_sheet(&sheet_name))
+ // The `local_path` only produces path formatting errors.
+ // If the path cannot be guaranteed to be correct,
+ // execution should not continue, so we unwrap()
+ .unwrap()
+ }
+}