Skip to content

Commit

Permalink
Refactor the table and add a ls cmd for projects
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Aug 20, 2024
1 parent e7d2f79 commit 9e337bc
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 57 deletions.
8 changes: 5 additions & 3 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
pub mod directory;
pub mod project;
pub mod template;

use self::{directory::DirectoryCli, project::ProjectCli, template::TemplateCli};
use clap::{Parser, Subcommand};
use self::{directory::DirectoryCli, template::TemplateCli};

// TODO: Make a `cli`directory with multiple files

/// A CLI for tmux session management
#[derive(Parser, Debug)]
Expand All @@ -30,4 +29,7 @@ pub enum Commands {
/// This command provides functionalities to interact with tmux sessions based on templates
#[command(alias = "temp", alias = "templ")]
Template(TemplateCli),

#[command(alias = "proj", alias = "projects")]
Project(ProjectCli),
}
20 changes: 20 additions & 0 deletions src/cli/project.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
pub struct ProjectCli {
#[command(subcommand)]
pub action: ProjectCommands,
}

#[derive(Subcommand, Debug)]
pub enum ProjectCommands {
#[command(alias = "ls")]
List(ProjectListArgs),
}

#[derive(Debug, Parser)]
pub struct ProjectListArgs {
/// Show minimal output for scripts
#[arg(short, long, default_value_t = false)]
pub minimal: bool,
}
1 change: 1 addition & 0 deletions src/cli/template.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::{Parser, Subcommand};
use std::path::PathBuf;

#[derive(Parser, Debug)]
pub struct TemplateCli {
#[command(subcommand)]
Expand Down
9 changes: 7 additions & 2 deletions src/commands/directory.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::{
cli::directory::{DirectoryCli, DirectoryCommands, ListDirectoryArgs, StartDirectoryArgs}, conditional_command, directories::{self, Directory}, helpers::{absolute_path, dir_name, Exit}, tmux::{attach, session_exists}, widgets::{heading::Heading, table::fmt_table}
cli::directory::{DirectoryCli, DirectoryCommands, ListDirectoryArgs, StartDirectoryArgs},
conditional_command,
directories::{self, Directory},
helpers::{absolute_path, dir_name, Exit},
tmux::{attach, session_exists},
widgets::{heading::Heading, table::Table},
};
use std::{collections::HashMap, path::PathBuf};
use tmux_interface::{NewSession, Tmux, TmuxCommand};
Expand All @@ -22,7 +27,7 @@ fn list_handler(args: ListDirectoryArgs) {

for (key, value) in categories {
println!("{}", Heading(key));
println!("{}", fmt_table(value));
println!("{}", Table::from_iter(value.iter()));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod directory;
pub mod init;
pub mod project;
pub mod template;
22 changes: 22 additions & 0 deletions src/commands/project.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::{
cli::project::{ProjectCli, ProjectCommands, ProjectListArgs},
projects::parse_project_config,
widgets::{heading::Heading, table::Table},
};

pub fn project_handler(args: ProjectCli) {
match args.action {
ProjectCommands::List(args) => list_handler(args),
}
}

fn list_handler(args: ProjectListArgs) {
for proj in parse_project_config() {
if args.minimal {
println!("{}", proj.name);
} else {
println!("{}", Heading(proj.name));
println!("{}", Table::from(proj.setup));
}
}
}
4 changes: 2 additions & 2 deletions src/commands/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
helpers::{absolute_path, dir_name, Exit},
templates::{apply_template, parse_template_config},
tmux::{attach, session_exists},
widgets::{heading::Heading, table::fmt_table},
widgets::{heading::Heading, table::Table},
};
use std::path::PathBuf;
use tmux_interface::{NewSession, Tmux, TmuxCommand};
Expand Down Expand Up @@ -32,7 +32,7 @@ fn list_handler(args: ListTemplateArgs) {
println!("{}", template.name);
} else {
println!("{}", Heading(template.name));
println!("{}", fmt_table(template.windows));
println!("{}", Table::from_iter(template.windows.iter()));
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/directories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ impl fmt::Display for Directory {
}
}

impl Table<String, String> for Directory {
fn table(&self) -> (String, String) {
let first_col = match (&self.icon, &self.name) {
impl From<&Directory> for Table<String, String> {
fn from(value: &Directory) -> Self {
let first_col = match (&value.icon, &value.name) {
(Some(icon), Some(name)) => format!("{} {}", icon, name),
(Some(icon), None) => icon.clone(),
(None, Some(name)) => name.clone(),
(None, None) => "No name".to_string(),
};

(first_col, self.path.display().to_string())
Self::from((first_col, value.path.display().to_string()))
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/init.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::helpers::get_config_dir;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::{
fs, io,
path::{Path, PathBuf},
};

fn create_config_dir() -> io::Result<PathBuf> {
let config_dir = get_config_dir();
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod directories;
mod helpers;
mod init;
mod macros;
mod projects;
mod templates;
mod tmux;
mod widgets;
Expand All @@ -17,5 +18,6 @@ fn main() {
cli::Commands::Init => commands::init::init_handler(),
cli::Commands::Directory(args) => commands::directory::directory_handler(args),
cli::Commands::Template(args) => commands::template::template_handler(args),
cli::Commands::Project(args) => commands::project::project_handler(args),
}
}
152 changes: 152 additions & 0 deletions src/projects.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use crate::{
exit,
helpers::{get_config_dir, Exit},
templates::{parse_template_config, Window},
widgets::table::Table,
};
use serde::Deserialize;
use std::fs;

#[derive(Debug, PartialEq, Eq)]
pub struct Project {
pub name: String,
pub setup: ProjectSetup,
}

#[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum ProjectSetup {
Template(String),
Windows(Vec<Window>),
}

impl From<ProjectSetup> for Table<String, String> {
fn from(value: ProjectSetup) -> Self {
let (template_name, windows) = match value {
ProjectSetup::Template(template_name) => {
let all_templates = parse_template_config();
let template = all_templates
.into_iter()
.find(|t| t.name == template_name)
.unwrap_or_else(|| exit!(1, "Template {} could not be found", template_name));

(Some(template_name), template.windows)
}
ProjectSetup::Windows(windows) => (None, windows),
};

let mut rows = Self::new(vec![(
"Template".to_string(),
template_name.unwrap_or("None".to_string()),
)])
.rows;
let windows = Self::from_iter(windows).rows;
rows.extend(windows);

Self::new(rows)
}
}

impl<'de> Deserialize<'de> for Project {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct RawProject {
name: String,
template: Option<String>,
windows: Option<Vec<Window>>,
}

let raw = RawProject::deserialize(deserializer)?;

let setup = if let Some(template) = raw.template {
ProjectSetup::Template(template)
} else if let Some(windows) = raw.windows {
ProjectSetup::Windows(windows)
} else {
return Err(serde::de::Error::custom(
"Expected either template or windows",
));
};

Ok(Project {
name: raw.name,
setup,
})
}
}

pub fn parse_project_config() -> Vec<Project> {
let projects_content =
fs::read_dir(get_config_dir().join("projects/")).exit(1, "Can't read template config");

let projects_raw: Vec<_> = projects_content
.filter_map(|x| x.ok())
.filter(|x| x.path().is_file())
.filter_map(|x| fs::read_to_string(x.path()).ok())
.collect();

projects_raw
.iter()
.filter_map(|x| serde_yaml::from_str::<Project>(x).ok())
.collect()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_parser() {
let project = serde_yaml::from_str::<Project>(
"name: OsmApp
root_dir: ~/GitHub/osmapp/
windows:
- name:  Neovim
panes:
- nvim
- name: Server
panes:
- yarn run dev",
)
.unwrap();

assert_eq!(
project,
Project {
name: "OsmApp".to_string(),
setup: ProjectSetup::Windows(vec![
Window {
name: Some(" Neovim".to_string()),
panes: vec!["nvim".to_string()],
layout: None,
},
Window {
name: Some("Server".to_string()),
panes: vec!["yarn run dev".to_string()],
layout: None,
}
])
}
);

let project = serde_yaml::from_str::<Project>(
"name: Dlool
root_dir: ~/SoftwareDevelopment/web/Dlool/dlool_frontend_v2/
template: Svelte",
)
.unwrap();

assert_eq!(
project,
Project {
name: "Dlool".to_string(),
setup: ProjectSetup::Template("Svelte".to_string())
}
);
}
}
19 changes: 14 additions & 5 deletions src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,27 @@ pub struct Template {
pub windows: Vec<Window>,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Window {
pub name: Option<String>,
pub layout: Option<String>,
pub panes: Vec<String>,
}

impl Table<String, String> for Window {
fn table(&self) -> (String, String) {
let name = self.name.clone().unwrap_or("No name".to_string());
// TODO: Merge From<&Window> and From<Window>
impl From<&Window> for Table<String, String> {
fn from(value: &Window) -> Self {
let name = value.name.clone().unwrap_or("No name".to_string());

Self::from((name, format!("{} Panes", value.panes.len())))
}
}

impl From<Window> for Table<String, String> {
fn from(value: Window) -> Self {
let name = value.name.clone().unwrap_or("No name".to_string());

(name, format!("{} Panes", self.panes.len()))
Self::from((name, format!("{} Panes", value.panes.len())))
}
}

Expand Down
Loading

0 comments on commit 9e337bc

Please sign in to comment.