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