summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/cmd_system.rs100
-rw-r--r--src/cmd/cmds.rs2
-rw-r--r--src/cmd/cmds/status.rs122
-rw-r--r--src/cmd/cmds/template.rs45
-rw-r--r--src/cmd/errors.rs139
-rw-r--r--src/cmd/processer.rs41
-rw-r--r--src/cmd/renderer.rs54
-rw-r--r--src/cmd/renderers.rs1
-rw-r--r--src/cmd/renderers/json_renderer.rs44
9 files changed, 0 insertions, 548 deletions
diff --git a/src/cmd/cmd_system.rs b/src/cmd/cmd_system.rs
deleted file mode 100644
index 09daf5a..0000000
--- a/src/cmd/cmd_system.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-use serde::Serialize;
-
-use crate::{
- cmd::{
- errors::{CmdExecuteError, CmdPrepareError, CmdProcessError, CmdRenderError},
- renderer::{JVRenderResult, JVResultRenderer},
- },
- r_println,
-};
-use std::future::Future;
-
-pub struct JVCommandContext {
- pub help: bool,
- pub confirmed: bool,
-}
-
-pub trait JVCommand<Argument, Input, Output, Renderer>
-where
- Argument: clap::Parser + Send + Sync,
- Input: Send + Sync,
- Output: Serialize + Send + Sync,
- Renderer: JVResultRenderer<Output> + Send + Sync,
-{
- /// Get help string for the command
- fn get_help_str() -> String;
-
- /// Process the command with a specified renderer, performing any necessary post-execution processing
- fn process_with_renderer_flag(
- args: Vec<String>,
- ctx: JVCommandContext,
- renderer: String,
- ) -> impl Future<Output = Result<JVRenderResult, CmdProcessError>> + Send
- where
- Self: Sync,
- {
- async move {
- let renderer_str = renderer.as_str();
- include!("renderers/_renderers.rs")
- }
- }
-
- /// performing any necessary post-execution processing
- fn process(
- args: Vec<String>,
- ctx: JVCommandContext,
- ) -> impl Future<Output = Result<JVRenderResult, CmdProcessError>> + Send
- where
- Self: Sync,
- {
- Self::process_with_renderer::<Renderer>(args, ctx)
- }
-
- /// Process the command output with a custom renderer,
- /// performing any necessary post-execution processing
- fn process_with_renderer<R: JVResultRenderer<Output> + Send + Sync>(
- args: Vec<String>,
- ctx: JVCommandContext,
- ) -> impl Future<Output = Result<JVRenderResult, CmdProcessError>> + Send
- where
- Self: Sync,
- {
- async move {
- let mut full_args = vec!["jv".to_string()];
- full_args.extend(args);
- let parsed_args = match Argument::try_parse_from(full_args) {
- Ok(args) => args,
- Err(_) => return Err(CmdProcessError::ParseError(Self::get_help_str())),
- };
- // If the help flag is used, skip execution and directly print help
- if ctx.help {
- let mut r = JVRenderResult::default();
- r_println!(r, "{}", Self::get_help_str());
- return Ok(r);
- }
- let input = match Self::prepare(parsed_args, ctx).await {
- Ok(input) => input,
- Err(e) => return Err(CmdProcessError::from(e)),
- };
- let output = match Self::exec(input).await {
- Ok(output) => output,
- Err(e) => return Err(CmdProcessError::from(e)),
- };
- match R::render(&output).await {
- Ok(r) => Ok(r),
- Err(e) => Err(CmdProcessError::from(e)),
- }
- }
- }
-
- /// Prepare to run the command,
- /// converting Clap input into the command's supported input
- fn prepare(
- args: Argument,
- ctx: JVCommandContext,
- ) -> impl Future<Output = Result<Input, CmdPrepareError>> + Send;
-
- /// Run the command phase,
- /// returning an output structure, waiting for rendering
- fn exec(input: Input) -> impl Future<Output = Result<Output, CmdExecuteError>> + Send;
-}
diff --git a/src/cmd/cmds.rs b/src/cmd/cmds.rs
deleted file mode 100644
index e06480c..0000000
--- a/src/cmd/cmds.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-pub mod _registry;
-pub mod status;
diff --git a/src/cmd/cmds/status.rs b/src/cmd/cmds/status.rs
deleted file mode 100644
index d73a28a..0000000
--- a/src/cmd/cmds/status.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use std::{
- collections::{HashMap, HashSet},
- path::PathBuf,
- time::SystemTime,
-};
-
-use clap::Parser;
-use just_enough_vcs::vcs::data::{
- local::workspace_analyzer::{
- CreatedRelativePathBuf, FromRelativePathBuf, LostRelativePathBuf, ModifiedRelativePathBuf,
- ToRelativePathBuf,
- },
- member::MemberId,
- sheet::SheetName,
- vault::virtual_file::VirtualFileId,
-};
-use serde::Serialize;
-
-use crate::{
- cmd::{
- cmd_system::{JVCommand, JVCommandContext},
- errors::{CmdExecuteError, CmdPrepareError, CmdRenderError},
- renderer::{JVRenderResult, JVResultRenderer},
- },
- utils::workspace_reader::LocalWorkspaceReader,
-};
-
-pub struct JVStatusCommand;
-
-#[derive(Parser, Debug)]
-pub struct JVStatusArgument;
-
-#[derive(Serialize)]
-pub struct JVStatusResult {
- pub current_account: MemberId,
- pub current_sheet: SheetName,
- pub moved: HashMap<VirtualFileId, (FromRelativePathBuf, ToRelativePathBuf)>,
- pub created: HashSet<CreatedRelativePathBuf>,
- pub lost: HashSet<LostRelativePathBuf>,
- pub erased: HashSet<PathBuf>,
- pub modified: HashSet<ModifiedRelativePathBuf>,
- pub update_time: SystemTime,
- pub now_time: SystemTime,
-}
-
-impl Default for JVStatusResult {
- fn default() -> Self {
- Self {
- current_account: MemberId::default(),
- current_sheet: SheetName::default(),
- moved: HashMap::default(),
- created: HashSet::default(),
- lost: HashSet::default(),
- erased: HashSet::default(),
- modified: HashSet::default(),
- update_time: SystemTime::now(),
- now_time: SystemTime::now(),
- }
- }
-}
-
-impl JVCommand<JVStatusArgument, JVStatusResult, JVStatusResult, JVStatusRenderer>
- for JVStatusCommand
-{
- async fn prepare(
- _args: JVStatusArgument,
- _ctx: JVCommandContext,
- ) -> Result<JVStatusResult, CmdPrepareError> {
- // Initialize a reader for the local workspace and a default result structure
- let mut reader = LocalWorkspaceReader::default();
- let mut input = JVStatusResult::default();
-
- // Analyze the current status of the local workspace
- // (detects changes like created, modified, moved, etc.)
- let analyzed = reader.analyze_local_status().await?;
-
- // Retrieve the current account (member) ID
- let account = reader.current_account().await?;
-
- // Retrieve the name of the current sheet
- let sheet_name = reader.sheet_name().await?;
-
- // Get the timestamp of the last update, defaulting to the current time if not available
- let update_time = reader
- .latest_info()
- .await?
- .update_instant
- .unwrap_or(SystemTime::now());
-
- // Record the current system time
- let now_time = SystemTime::now();
-
- // Populate the result structure with the gathered data
- input.current_account = account;
- input.current_sheet = sheet_name;
- input.moved = analyzed.moved;
- input.created = analyzed.created;
- input.lost = analyzed.lost;
- input.erased = analyzed.erased;
- input.modified = analyzed.modified;
- input.update_time = update_time;
- input.now_time = now_time;
-
- Ok(input)
- }
-
- async fn exec(input: JVStatusResult) -> Result<JVStatusResult, CmdExecuteError> {
- Ok(input) // Analyze command, no needs execute
- }
-
- fn get_help_str() -> String {
- "".to_string()
- }
-}
-
-pub struct JVStatusRenderer;
-
-impl JVResultRenderer<JVStatusResult> for JVStatusRenderer {
- async fn render(data: &JVStatusResult) -> Result<JVRenderResult, CmdRenderError> {
- todo!()
- }
-}
diff --git a/src/cmd/cmds/template.rs b/src/cmd/cmds/template.rs
deleted file mode 100644
index 1c56c29..0000000
--- a/src/cmd/cmds/template.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use clap::Parser;
-use serde::Serialize;
-
-use crate::subcmd::{
- cmd::JVCommand,
- errors::{CmdExecuteError, CmdPrepareError, CmdRenderError},
- renderer::{JVRenderResult, JVResultRenderer},
-};
-
-pub struct JVUnknownCommand;
-
-#[derive(Parser, Debug)]
-pub struct JVUnknownArgument;
-
-pub struct JVUnknownInput;
-
-#[derive(Serialize)]
-pub struct JVUnknownOutput;
-
-impl JVCommand<JVUnknownArgument, JVUnknownInput, JVUnknownOutput, JVStatusRenderer>
- for JVUnknownCommand
-{
- async fn prepare(
- _args: JVUnknownArgument,
- _ctx: JVCommandContext,
- ) -> Result<JVUnknownInput, CmdPrepareError> {
- todo!()
- }
-
- async fn exec(_input: JVUnknownInput) -> Result<JVUnknownOutput, CmdExecuteError> {
- todo!()
- }
-
- fn get_help_str() -> String {
- "".to_string()
- }
-}
-
-pub struct JVStatusRenderer;
-
-impl JVResultRenderer<JVUnknownOutput> for JVStatusRenderer {
- async fn render(_data: &JVUnknownOutput) -> Result<JVRenderResult, CmdRenderError> {
- todo!()
- }
-}
diff --git a/src/cmd/errors.rs b/src/cmd/errors.rs
deleted file mode 100644
index 358d15a..0000000
--- a/src/cmd/errors.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use just_enough_vcs::vcs::data::{member::MemberId, sheet::SheetName};
-
-#[derive(thiserror::Error, Debug)]
-pub enum CmdPrepareError {
- #[error("IO error: {0}")]
- Io(#[from] std::io::Error),
-
- #[error("{0}")]
- Error(String),
-
- #[error("LocalWorkspace not found")]
- LocalWorkspaceNotFound,
-
- #[error("LocalConfig not found")]
- LocalConfigNotFound,
-
- #[error("LatestInfo not found")]
- LatestInfoNotFound,
-
- #[error("LatestFileData of {0} not found")]
- LatestFileDataNotExist(MemberId),
-
- #[error("CachedSheet `{0}` not found")]
- CachedSheetNotFound(SheetName),
-
- #[error("LocalSheet `{0}/{1}` not found")]
- LocalSheetNotFound(MemberId, SheetName),
-
- #[error("LocalStatusAnalyzeFailed")]
- LocalStatusAnalyzeFailed,
-
- #[error("No sheet in use")]
- NoSheetInUse,
-}
-
-impl CmdPrepareError {
- pub fn new(msg: impl AsRef<str>) -> Self {
- CmdPrepareError::Error(msg.as_ref().to_string())
- }
-}
-
-#[derive(thiserror::Error, Debug)]
-pub enum CmdExecuteError {
- #[error("IO error: {0}")]
- Io(#[from] std::io::Error),
-
- #[error("Content not prepared, cannot run")]
- Prepare(#[from] CmdPrepareError),
-
- #[error("{0}")]
- Error(String),
-}
-
-impl CmdExecuteError {
- pub fn new(msg: impl AsRef<str>) -> Self {
- CmdExecuteError::Error(msg.as_ref().to_string())
- }
-}
-
-#[derive(thiserror::Error, Debug)]
-pub enum CmdRenderError {
- #[error("IO error: {0}")]
- Io(#[from] std::io::Error),
-
- #[error("Preparation failed, cannot render")]
- Prepare(#[from] CmdPrepareError),
-
- #[error("Execution failed, no output content obtained before rendering")]
- Execute(#[from] CmdExecuteError),
-
- #[error("{0}")]
- Error(String),
-
- #[error("Serialize failed, {0}")]
- SerializeFailed(String),
-
- #[error("Renderer `{0}` not found")]
- RendererNotFound(String),
-}
-
-impl CmdRenderError {
- pub fn new(msg: impl AsRef<str>) -> Self {
- CmdRenderError::Error(msg.as_ref().to_string())
- }
-}
-
-#[derive(thiserror::Error, Debug)]
-pub enum CmdProcessError {
- #[error("Prepare error: {0}")]
- Prepare(#[from] CmdPrepareError),
-
- #[error("Execute error: {0}")]
- Execute(#[from] CmdExecuteError),
-
- #[error("Render error: {0}")]
- Render(#[from] CmdRenderError),
-
- #[error("{0}")]
- Error(String),
-
- #[error("Node `{0}` not found!")]
- NoNodeFound(String),
-
- #[error("No matching command found")]
- NoMatchingCommand,
-
- #[error("Ambiguous command, multiple matches found")]
- AmbiguousCommand(Vec<String>),
-
- #[error("Parse error")]
- ParseError(String),
-}
-
-impl CmdProcessError {
- pub fn new(msg: impl AsRef<str>) -> Self {
- CmdProcessError::Error(msg.as_ref().to_string())
- }
-
- pub fn prepare_err(&self) -> Option<&CmdPrepareError> {
- match self {
- CmdProcessError::Prepare(e) => Some(e),
- _ => None,
- }
- }
-
- pub fn execute_err(&self) -> Option<&CmdExecuteError> {
- match self {
- CmdProcessError::Execute(e) => Some(e),
- _ => None,
- }
- }
-
- pub fn render_err(&self) -> Option<&CmdRenderError> {
- match self {
- CmdProcessError::Render(e) => Some(e),
- _ => None,
- }
- }
-}
diff --git a/src/cmd/processer.rs b/src/cmd/processer.rs
deleted file mode 100644
index f5fc2a6..0000000
--- a/src/cmd/processer.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use crate::cmd::cmd_system::JVCommandContext;
-use crate::cmd::cmds::_registry::{jv_cmd_nodes, jv_cmd_process_node};
-use crate::cmd::errors::CmdProcessError;
-use crate::cmd::renderer::JVRenderResult;
-
-pub async fn jv_cmd_process(
- args: Vec<String>,
- ctx: JVCommandContext,
- renderer_override: String,
-) -> Result<JVRenderResult, CmdProcessError> {
- let nodes = jv_cmd_nodes();
- let command = args.join(" ");
-
- // Find nodes that match the beginning of the command
- let matching_nodes: Vec<&String> = nodes
- .iter()
- .filter(|node| command.starts_with(node.as_str()))
- .collect();
-
- match matching_nodes.len() {
- 0 => {
- // No matching node found
- return Err(CmdProcessError::NoMatchingCommand);
- }
- 1 => {
- let matched_prefix = matching_nodes[0];
- let prefix_len = matched_prefix.split_whitespace().count();
- let trimmed_args: Vec<String> = args.into_iter().skip(prefix_len).collect();
- return jv_cmd_process_node(matched_prefix, trimmed_args, ctx, renderer_override).await;
- }
- _ => {
- // Multiple matching nodes found
- return Err(CmdProcessError::AmbiguousCommand(
- matching_nodes
- .iter()
- .map(|s| s.to_string())
- .collect::<Vec<String>>(),
- ));
- }
- }
-}
diff --git a/src/cmd/renderer.rs b/src/cmd/renderer.rs
deleted file mode 100644
index eefa0f6..0000000
--- a/src/cmd/renderer.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use std::fmt::{Display, Formatter};
-
-use serde::Serialize;
-
-use crate::cmd::errors::CmdRenderError;
-
-pub trait JVResultRenderer<Data>
-where
- Data: Serialize,
-{
- fn render(
- data: &Data,
- ) -> impl Future<Output = Result<JVRenderResult, CmdRenderError>> + Send + Sync;
-}
-
-#[derive(Default, Debug, PartialEq)]
-pub struct JVRenderResult {
- render_text: String,
-}
-
-impl Display for JVRenderResult {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}\n", self.render_text.trim())
- }
-}
-
-impl JVRenderResult {
- pub fn print(&mut self, text: &str) {
- self.render_text.push_str(text);
- }
-
- pub fn println(&mut self, text: &str) {
- self.render_text.push_str(text);
- self.render_text.push('\n');
- }
-
- pub fn clear(&mut self) {
- self.render_text.clear();
- }
-}
-
-#[macro_export]
-macro_rules! r_print {
- ($result:expr, $($arg:tt)*) => {
- $result.print(&format!($($arg)*));
- };
-}
-
-#[macro_export]
-macro_rules! r_println {
- ($result:expr, $($arg:tt)*) => {
- $result.println(&format!($($arg)*));
- };
-}
diff --git a/src/cmd/renderers.rs b/src/cmd/renderers.rs
deleted file mode 100644
index 91fa88e..0000000
--- a/src/cmd/renderers.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod json_renderer;
diff --git a/src/cmd/renderers/json_renderer.rs b/src/cmd/renderers/json_renderer.rs
deleted file mode 100644
index 14c1f81..0000000
--- a/src/cmd/renderers/json_renderer.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use serde::Serialize;
-use serde_json;
-
-use crate::{
- cmd::{
- errors::CmdRenderError,
- renderer::{JVRenderResult, JVResultRenderer},
- },
- r_print,
-};
-
-pub struct JVResultJsonRenderer;
-
-impl<T> JVResultRenderer<T> for JVResultJsonRenderer
-where
- T: Serialize + Sync,
-{
- async fn render(data: &T) -> Result<JVRenderResult, CmdRenderError> {
- let mut r = JVRenderResult::default();
- let json_string = serde_json::to_string(data)
- .map_err(|e| CmdRenderError::SerializeFailed(e.to_string()))?;
-
- r_print!(r, "{}", json_string);
-
- Ok(r)
- }
-}
-
-pub struct JVResultPrettyJsonRenderer;
-
-impl<T> JVResultRenderer<T> for JVResultPrettyJsonRenderer
-where
- T: Serialize + Sync,
-{
- async fn render(data: &T) -> Result<JVRenderResult, CmdRenderError> {
- let mut r = JVRenderResult::default();
- let json_string = serde_json::to_string_pretty(data)
- .map_err(|e| CmdRenderError::SerializeFailed(e.to_string()))?;
-
- r_print!(r, "{}", json_string);
-
- Ok(r)
- }
-}