smbcloud_cli/project/
crud_read.rs1use std::{fs::OpenOptions, io::Write};
2
3use crate::{
4 cli::CommandResult,
5 ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
6};
7use anyhow::{anyhow, Result};
8use log::debug;
9use smbcloud_model::project::{Config, Project};
10use smbcloud_networking::{environment::Environment, get_smb_token};
11use smbcloud_networking_project::crud_project_read::{get_project, get_projects};
12use spinners::Spinner;
13use tabled::{Table, Tabled};
14
15#[derive(Tabled)]
16struct ProjectRow {
17 #[tabled(rename = "ID")]
18 id: i32,
19 #[tabled(rename = "Name")]
20 name: String,
21 #[tabled(rename = "Repository")]
22 repository: String,
23 #[tabled(rename = "Description")]
24 description: String,
25}
26
27#[derive(Tabled)]
28struct ProjectDetailRow {
29 #[tabled(rename = "ID")]
30 id: i32,
31 #[tabled(rename = "Name")]
32 name: String,
33 #[tabled(rename = "Repository")]
34 repository: String,
35 #[tabled(rename = "Description")]
36 description: String,
37 #[tabled(rename = "Created at")]
38 created_at: String,
39 #[tabled(rename = "Updated at")]
40 updated_at: String,
41}
42
43pub async fn process_project_list(env: Environment) -> Result<CommandResult> {
44 let mut spinner = Spinner::new(
45 spinners::Spinners::SimpleDotsScrolling,
46 succeed_message("Loading"),
47 );
48 let token = get_smb_token(env).await?;
49 match get_projects(env, token).await {
50 Ok(projects) => {
51 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Loaded."));
52 let msg = if projects.is_empty() {
53 succeed_message("No projects found.")
54 } else {
55 succeed_message("Showing all projects.")
56 };
57 show_projects(projects);
58 Ok(CommandResult {
59 spinner: Spinner::new(
60 spinners::Spinners::SimpleDotsScrolling,
61 succeed_message("Loading"),
62 ),
63 symbol: succeed_symbol(),
64 msg,
65 })
66 }
67 Err(e) => {
68 println!("Error: {e:#?}");
69 Ok(CommandResult {
70 spinner,
71 symbol: fail_symbol(),
72 msg: fail_message("Failed to get all projects."),
73 })
74 }
75 }
76}
77
78pub async fn process_project_show(env: Environment, id: String) -> Result<CommandResult> {
79 let mut spinner = Spinner::new(
80 spinners::Spinners::SimpleDotsScrolling,
81 succeed_message("Loading"),
82 );
83 let access_token = get_smb_token(env).await?;
84 match get_project(env, access_token, id).await {
85 Ok(project) => {
86 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Loaded."));
87 let message = succeed_message(&format!("Showing project {}.", &project.name));
88 show_project_detail(&project);
89 Ok(CommandResult {
90 spinner: Spinner::new(
91 spinners::Spinners::SimpleDotsScrolling,
92 succeed_message("Loading"),
93 ),
94 symbol: succeed_symbol(),
95 msg: message,
96 })
97 }
98 Err(e) => {
99 spinner.stop_and_persist(&fail_symbol(), fail_message("Failed."));
100 Err(anyhow!("{e}"))
101 }
102 }
103}
104
105pub(crate) fn show_projects(projects: Vec<Project>) {
106 if projects.is_empty() {
107 return;
108 }
109 let rows: Vec<ProjectRow> = projects
110 .into_iter()
111 .map(|p| ProjectRow {
112 id: p.id,
113 name: p.name,
114 repository: p.repository,
115 description: p.description.unwrap_or("-".to_owned()),
116 })
117 .collect();
118 let table = Table::new(rows);
119 println!("{table}");
120}
121
122pub(crate) fn show_project_detail(project: &Project) {
123 let row = ProjectDetailRow {
124 id: project.id,
125 name: project.name.clone(),
126 repository: project.repository.clone(),
127 description: project.description.clone().unwrap_or("-".to_owned()),
128 created_at: project.created_at.date_naive().to_string(),
129 updated_at: project.updated_at.date_naive().to_string(),
130 };
131 let table = Table::new(vec![row]);
132 println!("{table}");
133}
134
135pub(crate) async fn process_project_use(env: Environment, id: String) -> Result<CommandResult> {
136 let access_token = get_smb_token(env).await?;
137 let project = get_project(env, access_token, id).await?;
138
139 let config = Config {
140 current_project: Some(project),
141 current_auth_app: None,
142 };
143
144 let spinner = Spinner::new(
145 spinners::Spinners::SimpleDotsScrolling,
146 succeed_message("Loading"),
147 );
148 match home::home_dir() {
149 Some(path) => {
150 debug!("{}", path.to_str().unwrap());
151 let mut file = OpenOptions::new()
152 .create(true)
153 .truncate(true)
154 .write(true)
155 .open([path.to_str().unwrap(), "/.smb/config.json"].join(""))?;
156 let json = serde_json::to_string(&config)?;
157 file.write_all(json.as_bytes())?;
158
159 Ok(CommandResult {
160 spinner,
161 symbol: succeed_symbol(),
162 msg: succeed_message("Use project successful."),
163 })
164 }
165 None => {
166 let error = anyhow!("Failed to get home directory.");
167 Err(error)
168 }
169 }
170}