5 files changed
+130
-10
Cargo.lock
+52
@@ -148,6 +148,26 @@ dependencies = [
148
"zeroize",
149
]
150
151
+[[package]]
152
+name = "dirs"
153
+version = "4.0.0"
154
+source = "registry+https://github.com/rust-lang/crates.io-index"
155
+checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
156
+dependencies = [
157
+ "dirs-sys",
158
+]
159
+
160
+[[package]]
161
+name = "dirs-sys"
162
+version = "0.3.7"
163
+source = "registry+https://github.com/rust-lang/crates.io-index"
164
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
165
+dependencies = [
166
+ "libc",
167
+ "redox_users",
168
+ "winapi",
169
+]
170
+
171
[[package]]
172
name = "encode_unicode"
173
version = "0.3.6"
@@ -756,6 +776,17 @@ dependencies = [
776
"bitflags",
777
]
778
779
+[[package]]
780
+name = "redox_users"
781
+version = "0.4.3"
782
+source = "registry+https://github.com/rust-lang/crates.io-index"
783
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
784
+dependencies = [
785
+ "getrandom",
786
+ "redox_syscall",
787
+ "thiserror",
788
+]
789
+
790
[[package]]
791
name = "regex"
792
version = "1.7.1"
@@ -982,6 +1013,7 @@ dependencies = [
1013
"clap",
1014
"console",
1015
"dialoguer",
1016
+ "dirs",
1017
"home",
1018
"regex",
1019
"reqwest",
@@ -1077,6 +1109,26 @@ dependencies = [
1109
"winapi-util",
1110
]
1111
1112
+[[package]]
1113
+name = "thiserror"
1114
+version = "1.0.39"
1115
+source = "registry+https://github.com/rust-lang/crates.io-index"
1116
+checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
1117
+dependencies = [
1118
+ "thiserror-impl",
1119
+]
1120
+
1121
+[[package]]
1122
+name = "thiserror-impl"
1123
+version = "1.0.39"
1124
+source = "registry+https://github.com/rust-lang/crates.io-index"
1125
+checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
1126
+dependencies = [
1127
+ "proc-macro2",
1128
+ "quote",
1129
+ "syn",
1130
+]
1131
+
1132
[[package]]
1133
name = "thread_local"
1134
version = "1.1.7"
Cargo.toml
+1
@@ -14,6 +14,7 @@ name = "smb"
14
path = "src/main.rs"
15
16
[dependencies]
17
+dirs = "4.0.0"
18
anyhow = "1.0.58"
19
clap = { version = "4.1.6", features = ["derive"] }
20
console = "0.15.0"
src/main.rs
+1
-1
@@ -157,6 +157,6 @@ async fn run() -> Result<CommandResult> {
157
}),
158
}
159
}
160
- Commands::Projects { command } => projects::process(command),
160
+ Commands::Projects { command } => projects::process(command).await,
161
}
162
}
src/projects/crud/mod.rs
new
+43
@@ -0,0 +1,43 @@
1
+use crate::{constants::BASE_URL, debug};
2
+use anyhow::{anyhow, Result};
3
+use reqwest::Client;
4
+use serde::Deserialize;
5
+
6
+#[derive(Deserialize, Debug)]
7
+pub struct Project {
8
+ id: i32,
9
+ name: String,
10
+ created_at: String,
11
+ updated_at: String,
12
+}
13
+
14
+pub async fn get_all() -> Result<Vec<Project>> {
15
+ // Get current token
16
+ let token = get_token().await.unwrap();
17
+
18
+ let response = Client::new()
19
+ .get([BASE_URL, "v1/projects"].join(""))
20
+ .header("Authorization", token)
21
+ .send()
22
+ .await?;
23
+
24
+ match response.status() {
25
+ reqwest::StatusCode::OK => {
26
+ let projects: Vec<Project> = response.json().await?;
27
+ Ok(projects)
28
+ }
29
+ _ => {
30
+ debug!("Failed to get all projects.", response.status());
31
+ Err(anyhow!("Failed to login."))
32
+ }
33
+ }
34
+}
35
+
36
+async fn get_token() -> Result<String> {
37
+ if let Some(mut path) = dirs::home_dir() {
38
+ path.push(".smb/token");
39
+ std::fs::read_to_string(path).map_err(|e| anyhow!(e))
40
+ } else {
41
+ Err(anyhow!("Failed to get home directory."))
42
+ }
43
+}
src/projects/mod.rs
+33
-9
@@ -1,3 +1,5 @@
1
+mod crud;
2
+
3
use anyhow::Result;
4
use clap::Subcommand;
5
use console::style;
@@ -5,6 +7,8 @@ use spinners::Spinner;
7
8
use crate::util::CommandResult;
9
10
+use self::crud::get_all;
11
+
12
#[derive(Subcommand)]
13
pub enum Commands {
14
#[clap(about = "Add new project.")]
@@ -25,10 +29,14 @@ pub enum Commands {
29
},
30
31
#[clap(about = "Delete a project.")]
28
- Delete {},
32
+ Delete {
33
+ /// Project name
34
+ #[clap(short, long, required = true)]
35
+ name: String,
36
+ },
37
}
38
31
-pub fn process(commands: Commands) -> Result<CommandResult> {
39
+pub async fn process(commands: Commands) -> Result<CommandResult> {
40
let spinner = Spinner::new(
41
spinners::Spinners::SimpleDotsScrolling,
42
style("Logging in...").green().bold().to_string(),
@@ -46,20 +54,36 @@ pub fn process(commands: Commands) -> Result<CommandResult> {
54
msg: format!("Creating a project {project_name}."),
55
})
56
}
49
- Commands::List {} => Ok(CommandResult {
50
- spinner,
51
- symbol: "✅".to_owned(),
52
- msg: "You are signed up! Check your email to confirm your account.".to_owned(),
53
- }),
57
+ Commands::List {} => {
58
+ // Get all
59
+ match get_all().await {
60
+ Ok(projects) => {
61
+ println!("Projects: {:#?}", projects);
62
+ Ok(CommandResult {
63
+ spinner,
64
+ symbol: "✅".to_owned(),
65
+ msg: "Showing all projects.".to_owned(),
66
+ })
67
+ }
68
+ Err(e) => {
69
+ println!("Error: {:#?}", e);
70
+ Ok(CommandResult {
71
+ spinner,
72
+ symbol: "❌".to_owned(),
73
+ msg: "Failed to get all projects.".to_owned(),
74
+ })
75
+ }
76
+ }
77
+ }
78
Commands::Show { name } => Ok(CommandResult {
79
spinner,
80
symbol: "✅".to_owned(),
81
msg: format!("Showing project {name}."),
82
}),
59
- Commands::Delete {} => Ok(CommandResult {
83
+ Commands::Delete { name } => Ok(CommandResult {
84
spinner,
85
symbol: "✅".to_owned(),
62
- msg: "You are signed up! Check your email to confirm your account.".to_owned(),
86
+ msg: format!("Deleting project {name}."),
87
}),
88
}
89
}