1use crate::backend::utils::unregister;
2use crate::setup::{dir, Dirs};
3use crate::Type;
4use anyhow::Result;
5use std::os::unix::fs::symlink;
6use std::process::Command;
7
8pub struct Tag {
9 name: String,
10}
11
12impl Tag {
13 pub fn from(name: &str) -> Self {
14 Self {
15 name: name.to_string(),
16 }
17 }
18
19 pub fn init(&self, templates: &Vec<&str>, projects: &Vec<&str>) -> Result<()> {
25 let tag_data_dir = dir(Dirs::Tags)?;
26 let tag_dir = tag_data_dir.join(&self.name);
27 let tag_templates_dir = &tag_dir.join("templates");
28 let tag_projects_dir = &tag_dir.join("projects");
29
30 if !tag_dir.is_dir() {
32 std::fs::create_dir(&tag_dir)?;
33 std::fs::create_dir(&tag_templates_dir)?;
34 std::fs::create_dir(&tag_projects_dir)?;
35 }
36
37 let templates_dir = dir(Dirs::Templates)?;
40 for template in templates {
41 let template_path = &templates_dir.join(&template).canonicalize()?;
42 let tag_template_symlink = &tag_templates_dir.join(&template);
43 if !tag_template_symlink.is_symlink() {
44 symlink(template_path, tag_template_symlink)?;
45 }
46 }
47
48 let projects_dir = dir(Dirs::Projects)?;
49 for project in projects {
50 let project_path = &projects_dir.join(&project).canonicalize()?;
51 let tag_project_symlink = &tag_projects_dir.join(&project);
52 if !tag_project_symlink.is_symlink() {
53 symlink(project_path, tag_project_symlink)?;
54 }
55 }
56
57 Ok(())
58 }
59
60 pub fn list(tag: &Option<String>) -> Result<String> {
64 let tag_dir = if let Some(tag) = tag {
65 dir(Dirs::Tags)?.join(tag)
66 } else {
67 dir(Dirs::Tags)?
68 };
69
70 let output = Command::new("tree")
71 .arg(tag_dir.display().to_string())
72 .output()?;
73 Ok(std::str::from_utf8(&output.stdout)?.to_string())
74 }
75
76 pub fn remove(&self, templates: &Vec<&str>, projects: &Vec<&str>) -> Result<()> {
77 if templates.len() == 0 && projects.len() == 0 {
78 unregister(Type::Tag, &self.name)
79 } else {
80 let tag_templates_dir = dir(Dirs::Tags)?.join(&self.name).join("templates");
81 let tag_projects_dir = dir(Dirs::Tags)?.join(&self.name).join("projects");
82
83 for template in templates {
84 let template_link = tag_templates_dir.join(template);
85 if template_link.is_symlink() {
86 std::fs::remove_file(template_link)?;
87 }
88 }
89
90 for project in projects {
91 let project_link = tag_projects_dir.join(project);
92 if project_link.is_symlink() {
93 std::fs::remove_file(project_link)?;
94 }
95 }
96
97 Ok(())
98 }
99 }
100}