Refactor networking: move Environment to network crate
- Move `environment.rs` to the new `network` crate and update imports - Remove direct dependency on `smbcloud_networking::environment` - Move token file helpers to `cli::token` module - Update Cargo.toml dependencies and workspace usage - Update project networking modules to use `network::environment::Environment`
Seto Elkahfi committed
Jul 26, 2025 at 18:26 UTC
863371d2c4ee36813b14739cfd6e9df2a0824127
35 files changed
+95
-100
Cargo.lock
+2
-13
@@ -1190,6 +1190,7 @@ dependencies = [
1190
name = "network"
1191
version = "0.1.0"
1192
dependencies = [
1193
+ "clap",
1194
"log",
1195
"reqwest",
1196
"serde",
@@ -1937,18 +1938,7 @@ dependencies = [
1938
name = "smbcloud-networking"
1939
version = "0.3.20"
1940
dependencies = [
1940
- "anyhow",
1941
- "async-trait",
1942
- "clap",
1943
- "dirs",
1944
- "home",
1945
- "log",
1946
- "maybe-async",
1947
- "reqwest",
1948
- "serde",
1949
- "serde_json",
1950
- "smbcloud-model",
1951
- "thiserror 2.0.12",
1941
+ "network",
1942
"url-builder",
1943
]
1944
@@ -1966,7 +1956,6 @@ dependencies = [
1956
"anyhow",
1957
"async-trait",
1958
"dirs",
1969
- "home",
1959
"log",
1960
"maybe-async",
1961
"network",
crates/cli/src/account/forgot/mod.rs
+2
-3
@@ -4,12 +4,11 @@ use crate::{
4
};
5
use anyhow::Result;
6
use dialoguer::{theme::ColorfulTheme, Input, Password};
7
+use network::environment::Environment;
8
use reqwest::{Client, StatusCode};
9
use serde::{Deserialize, Serialize};
10
use smbcloud_model::forgot::{Args, Email, Param, UserUpdatePassword};
10
-use smbcloud_networking::{
11
- constants::PATH_USERS_PASSWORD, environment::Environment, smb_base_url_builder,
12
-};
11
+use smbcloud_networking::{constants::PATH_USERS_PASSWORD, smb_base_url_builder};
12
use smbcloud_utils::email_validation;
13
use spinners::Spinner;
14
crates/cli/src/account/lib.rs
+7
-6
@@ -1,6 +1,8 @@
1
+use crate::token::smb_token_file_path;
2
use anyhow::{anyhow, Result};
3
use console::style;
4
use log::debug;
5
+use network::environment::Environment;
6
use regex::Regex;
7
use reqwest::{Client, Response, StatusCode};
8
use smbcloud_model::account::SmbAuthorization;
@@ -8,8 +10,7 @@ use smbcloud_networking::{
10
constants::{
11
GH_OAUTH_CLIENT_ID, GH_OAUTH_REDIRECT_HOST, GH_OAUTH_REDIRECT_PORT, PATH_AUTHORIZE,
12
},
11
- environment::Environment,
12
- smb_base_url_builder, smb_token_file_path,
13
+ smb_base_url_builder,
14
};
15
use spinners::Spinner;
16
use std::{
@@ -105,7 +106,7 @@ fn handle_connection(mut stream: TcpStream, tx: Sender<String>) {
106
<meta charset='utf-8'>
107
<title>Hello!</title>
108
</head>
108
-
109
+
110
<body>
111
<h1>Authenticated!</h1>
112
<p>Back to the terminal console to finish your registration.</p>
@@ -118,17 +119,17 @@ fn handle_connection(mut stream: TcpStream, tx: Sender<String>) {
119
"HTTP/1.1 404 NOT FOUND",
120
"<!DOCTYPE html>
121
<html lang='en'>
121
-
122
+
123
<head>
124
<meta charset='utf-8'>
125
<title>404 Not found</title>
126
</head>
126
-
127
+
128
<body>
129
<h1>Oops!</h1>
130
<p>Sorry, I don't know what you're asking for.</p>
131
</body>
131
-
132
+
133
</html>",
134
)
135
}
crates/cli/src/account/login/process.rs
+1
-1
@@ -10,6 +10,7 @@ use anyhow::{anyhow, Result};
10
use console::style;
11
use dialoguer::{console::Term, theme::ColorfulTheme, Confirm, Input, Password, Select};
12
use log::debug;
13
+use network::environment::Environment;
14
use reqwest::{Client, StatusCode};
15
use smbcloud_model::{
16
account::{ErrorCode, GithubInfo, SmbAuthorization, User},
@@ -22,7 +23,6 @@ use smbcloud_networking::{
23
PATH_LINK_GITHUB_ACCOUNT, PATH_RESEND_CONFIRMATION, PATH_RESET_PASSWORD_INSTRUCTIONS,
24
PATH_USERS_PASSWORD, PATH_USERS_SIGN_IN,
25
},
25
- environment::Environment,
26
smb_base_url_builder,
27
};
28
use smbcloud_utils::email_validation;
crates/cli/src/account/logout/mod.rs
+3
-4
@@ -1,10 +1,9 @@
1
+use crate::token::{get_smb_token, smb_token_file_path};
2
use anyhow::{anyhow, Result};
3
use dialoguer::{theme::ColorfulTheme, Confirm};
4
+use network::environment::Environment;
5
use reqwest::{Client, StatusCode};
4
-use smbcloud_networking::{
5
- constants::PATH_USERS_SIGN_OUT, environment::Environment, get_smb_token, smb_base_url_builder,
6
- smb_token_file_path,
7
-};
6
+use smbcloud_networking::{constants::PATH_USERS_SIGN_OUT, smb_base_url_builder};
7
use spinners::Spinner;
8
use std::fs;
9
crates/cli/src/account/me/mod.rs
+3
-3
@@ -1,14 +1,14 @@
1
use crate::account::lib::is_logged_in;
2
+use crate::token::get_smb_token;
3
use crate::{
4
cli::CommandResult,
5
ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
6
};
7
use anyhow::{anyhow, Result};
8
+use network::environment::Environment;
9
use reqwest::{Client, StatusCode};
10
use smbcloud_model::account::User;
9
-use smbcloud_networking::{
10
- constants::PATH_USERS_ME, environment::Environment, get_smb_token, smb_base_url_builder,
11
-};
11
+use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
12
use spinners::Spinner;
13
use tabled::{Table, Tabled};
14
crates/cli/src/account/mod.rs
+1
-1
@@ -10,7 +10,7 @@ use self::{cli::Commands, forgot::process_forgot, login::process_login, signup::
10
use crate::cli::CommandResult;
11
use anyhow::Result;
12
use logout::process_logout;
13
-use smbcloud_networking::environment::Environment;
13
+use network::environment::Environment;
14
15
pub async fn process_account(env: Environment, commands: Commands) -> Result<CommandResult> {
16
match commands {
crates/cli/src/account/signup/process.rs
+3
-3
@@ -1,4 +1,5 @@
1
use super::SignupMethod;
2
+use crate::token::smb_token_file_path;
3
use crate::{
4
account::lib::authorize_github,
5
cli::CommandResult,
@@ -7,12 +8,11 @@ use crate::{
8
use anyhow::{anyhow, Result};
9
use dialoguer::{console::Term, theme::ColorfulTheme, Input, Password, Select};
10
use log::debug;
11
+use network::environment::Environment;
12
use reqwest::{Client, StatusCode};
13
use serde::Serialize;
14
use smbcloud_model::signup::{SignupEmailParams, SignupResult, SignupUserEmail};
13
-use smbcloud_networking::{
14
- constants::PATH_USERS, environment::Environment, smb_base_url_builder, smb_token_file_path,
15
-};
15
+use smbcloud_networking::{constants::PATH_USERS, smb_base_url_builder};
16
use smbcloud_utils::email_validation;
17
use spinners::Spinner;
18
crates/cli/src/cli/mod.rs
+1
-1
@@ -1,6 +1,6 @@
1
use crate::{account, project};
2
use clap::{Parser, Subcommand};
3
-use smbcloud_networking::environment::Environment;
3
+use network::environment::Environment;
4
use spinners::Spinner;
5
6
pub struct CommandResult {
crates/cli/src/deploy/config.rs
+1
-1
@@ -3,13 +3,13 @@ use crate::{
3
ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
4
};
5
use git2::{Cred, CredentialType, Error};
6
+use network::environment::Environment;
7
use serde::{Deserialize, Serialize};
8
use smbcloud_model::{
9
account::User,
10
error_codes::{ErrorCode, ErrorResponse},
11
project::Project,
12
};
12
-use smbcloud_networking::environment::Environment;
13
use smbcloud_networking_project::crud_project_read::get_project;
14
use spinners::Spinner;
15
use std::{fs, path::Path};
crates/cli/src/deploy/mod.rs
+2
-1
@@ -3,6 +3,7 @@ mod git;
3
mod remote_messages;
4
mod setup;
5
6
+use crate::token::get_smb_token;
7
use crate::{
8
account::{lib::is_logged_in, login::process_login, me::me},
9
cli::CommandResult,
@@ -14,9 +15,9 @@ use anyhow::{anyhow, Result};
15
use config::check_config;
16
use git::remote_deployment_setup;
17
use git2::{PushOptions, RemoteCallbacks, Repository};
18
+use network::environment::Environment;
19
use remote_messages::{build_next_app, start_server};
20
use smbcloud_model::project::{DeploymentPayload, DeploymentStatus};
19
-use smbcloud_networking::{environment::Environment, get_smb_token};
21
use smbcloud_networking_project::{
22
crud_project_deployment_create::create_deployment, crud_project_deployment_update::update,
23
};
crates/cli/src/deploy/setup.rs
+2
-1
@@ -1,11 +1,12 @@
1
+use crate::token::get_smb_token;
2
use crate::{deploy::config::Config, ui::highlight};
3
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
4
+use network::environment::Environment;
5
use regex::Regex;
6
use smbcloud_model::{
7
error_codes::{ErrorCode, ErrorResponse},
8
project::{Project, ProjectCreate},
9
};
8
-use smbcloud_networking::{environment::Environment, get_smb_token};
10
use smbcloud_networking_project::{
11
crud_project_create::create_project, crud_project_read::get_projects,
12
};
crates/cli/src/lib.rs
+1
@@ -2,4 +2,5 @@ pub mod account;
2
pub mod cli;
3
pub mod deploy;
4
pub mod project;
5
+mod token;
6
mod ui;
crates/cli/src/main.rs
+1
-1
@@ -1,6 +1,7 @@
1
use anyhow::{anyhow, Result};
2
use clap::Parser;
3
use console::style;
4
+use network::environment::Environment;
5
use network::network::check_internet_connection;
6
use smbcloud_cli::account::login::process_login;
7
use smbcloud_cli::account::logout::process_logout;
@@ -13,7 +14,6 @@ use smbcloud_cli::{
14
cli::{Cli, Commands},
15
deploy::process_deploy,
16
};
16
-use smbcloud_networking::environment::Environment;
17
use std::{
18
fs::{create_dir_all, OpenOptions},
19
path::PathBuf,
crates/cli/src/project/crud_create.rs
+3
-2
@@ -1,3 +1,4 @@
1
+use crate::token::get_smb_token;
2
use crate::{
3
account::{lib::is_logged_in, login::process_login},
4
cli::CommandResult,
@@ -7,8 +8,8 @@ use anyhow::{anyhow, Result};
8
use chrono::Utc;
9
use console::style;
10
use dialoguer::{theme::ColorfulTheme, Input};
11
+use network::environment::Environment;
12
use smbcloud_model::project::ProjectCreate;
11
-use smbcloud_networking::{environment::Environment, get_smb_token};
13
use smbcloud_networking_project::crud_project_create::create_project;
14
use spinners::Spinner;
15
@@ -94,7 +95,7 @@ name = "{repository_name}"
95
repository = "{repository_name}"
96
description = "{description}"
97
created_at = "{now}"
97
-updated_at = "{now}"
98
+updated_at = "{now}"
99
"#,
100
),
101
)?;
crates/cli/src/project/crud_delete.rs
+2
-1
@@ -1,3 +1,4 @@
1
+use crate::token::get_smb_token;
2
use crate::{
3
account::lib::is_logged_in,
4
cli::CommandResult,
@@ -5,7 +6,7 @@ use crate::{
6
};
7
use anyhow::{anyhow, Result};
8
use dialoguer::{theme::ColorfulTheme, Input};
8
-use smbcloud_networking::{environment::Environment, get_smb_token};
9
+use network::environment::Environment;
10
use smbcloud_networking_project::crud_project_delete::delete_project;
11
use spinners::Spinner;
12
crates/cli/src/project/crud_read.rs
+2
-1
@@ -1,13 +1,14 @@
1
use std::{fs::OpenOptions, io::Write};
2
3
+use crate::token::get_smb_token;
4
use crate::{
5
cli::CommandResult,
6
ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
7
};
8
use anyhow::{anyhow, Result};
9
use log::debug;
10
+use network::environment::Environment;
11
use smbcloud_model::project::{Config, Project};
10
-use smbcloud_networking::{environment::Environment, get_smb_token};
12
use smbcloud_networking_project::crud_project_read::{get_project, get_projects};
13
use spinners::Spinner;
14
use tabled::{Table, Tabled};
crates/cli/src/project/crud_update.rs
+2
-1
@@ -1,6 +1,7 @@
1
+use crate::token::get_smb_token;
2
use anyhow::{anyhow, Result};
3
use dialoguer::{theme::ColorfulTheme, Input};
3
-use smbcloud_networking::{environment::Environment, get_smb_token};
4
+use network::environment::Environment;
5
use smbcloud_networking_project::{
6
crud_project_read::get_project, crud_project_update::update_project_description,
7
};
crates/cli/src/project/deployment.rs
+2
-1
@@ -1,11 +1,12 @@
1
+use crate::token::get_smb_token;
2
use crate::{
3
cli::CommandResult,
4
deploy::config::{check_config, check_project},
5
ui::{succeed_message, succeed_symbol},
6
};
7
use anyhow::Result;
8
+use network::environment::Environment;
9
use smbcloud_model::project::Deployment;
8
-use smbcloud_networking::{environment::Environment, get_smb_token};
10
use smbcloud_networking_project::crud_project_deployment_read::{get_deployment, get_deployments};
11
use spinners::Spinner;
12
use tabled::{Table, Tabled};
crates/cli/src/project/process.rs
+1
-1
@@ -10,7 +10,7 @@ use crate::{
10
},
11
};
12
use anyhow::Result;
13
-use smbcloud_networking::environment::Environment;
13
+use network::environment::Environment;
14
15
pub async fn process_project(env: Environment, commands: Commands) -> Result<CommandResult> {
16
match commands {
crates/cli/src/token/mod.rs
new
+33
@@ -0,0 +1,33 @@
1
+use anyhow::{anyhow, Result};
2
+use dirs::home_dir;
3
+use log::debug;
4
+use network::environment::Environment;
5
+use std::path::{Path, PathBuf};
6
+
7
+pub async fn get_smb_token(env: Environment) -> Result<String> {
8
+ if let Some(path) = smb_token_file_path(env) {
9
+ std::fs::read_to_string(path).map_err(|e| {
10
+ debug!("Error while reading token: {}", &e);
11
+ anyhow!("Error while reading token. Are you logged in?")
12
+ })
13
+ } else {
14
+ Err(anyhow!("Failed to get home directory. Are you logged in?"))
15
+ }
16
+}
17
+
18
+pub fn smb_token_file_path(env: Environment) -> Option<PathBuf> {
19
+ match home_dir() {
20
+ Some(home_path) => {
21
+ let token_path = [&env.smb_dir(), "/token"].join("");
22
+ let token_file = home_path.join(Path::new(&token_path));
23
+ if token_file.exists() && token_file.is_file() {
24
+ return Some(token_file);
25
+ }
26
+ None
27
+ }
28
+ None => {
29
+ debug!("Failed to get home directory.");
30
+ None
31
+ }
32
+ }
33
+}
crates/network/Cargo.toml
+1
@@ -8,6 +8,7 @@ crate-type = ["cdylib", "rlib"]
8
9
[dependencies]
10
log = { workspace = true }
11
+clap = { workspace = true, features = ["derive", "env"] }
12
reqwest = { workspace = true, features = ["json"] }
13
serde = { workspace = true, features = ["derive"] }
14
serde_json = { workspace = true }
crates/network/src/environment.rs
renamed
crates/network/src/lib.rs
+1
@@ -1 +1,2 @@
1
+pub mod environment;
2
pub mod network;
crates/smbcloud-networking-project/Cargo.toml
-1
@@ -24,7 +24,6 @@ crate-type = ["cdylib", "rlib"]
24
anyhow = { workspace = true }
25
async-trait = { workspace = true, optional = true }
26
dirs = { workspace = true }
27
-home = { workspace = true }
27
log = { workspace = true }
28
network = { workspace = true }
29
maybe-async = { workspace = true, features = ["is_sync"] }
crates/smbcloud-networking-project/src/crud_project_create.rs
+2
-1
@@ -1,11 +1,12 @@
1
use anyhow::Result;
2
+use network::environment::Environment;
3
use network::network::request;
4
use reqwest::Client;
5
use smbcloud_model::{
6
error_codes::ErrorResponse,
7
project::{Project, ProjectCreate},
8
};
8
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
9
+use smbcloud_networking::constants::SMB_USER_AGENT;
10
11
use crate::url_builder::build_project_url;
12
crates/smbcloud-networking-project/src/crud_project_delete.rs
+2
-1
@@ -1,8 +1,9 @@
1
use crate::url_builder::build_project_url_with_id;
2
+use network::environment::Environment;
3
use network::network::request;
4
use reqwest::Client;
5
use smbcloud_model::error_codes::ErrorResponse;
5
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6
+use smbcloud_networking::constants::SMB_USER_AGENT;
7
8
pub async fn delete_project(
9
env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_create.rs
+2
-1
@@ -1,12 +1,13 @@
1
use crate::url_builder::build_project_deployment_index;
2
use anyhow::Result;
3
+use network::environment::Environment;
4
use network::network::request;
5
use reqwest::Client;
6
use smbcloud_model::{
7
error_codes::ErrorResponse,
8
project::{Deployment, DeploymentPayload},
9
};
9
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
10
+use smbcloud_networking::constants::SMB_USER_AGENT;
11
12
pub async fn create_deployment(
13
env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_read.rs
+2
-1
@@ -1,9 +1,10 @@
1
use crate::url_builder::{build_project_deployment, build_project_deployment_index};
2
use anyhow::Result;
3
+use network::environment::Environment;
4
use network::network::request;
5
use reqwest::Client;
6
use smbcloud_model::{error_codes::ErrorResponse, project::Deployment};
6
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
7
+use smbcloud_networking::constants::SMB_USER_AGENT;
8
9
pub async fn get_deployments(
10
env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_update.rs
+2
-1
@@ -1,11 +1,12 @@
1
use anyhow::Result;
2
+use network::environment::Environment;
3
use network::network::request;
4
use reqwest::Client;
5
use smbcloud_model::{
6
error_codes::ErrorResponse,
7
project::{Deployment, DeploymentPayload},
8
};
8
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
9
+use smbcloud_networking::constants::SMB_USER_AGENT;
10
11
use crate::url_builder::build_project_deployment;
12
crates/smbcloud-networking-project/src/crud_project_read.rs
+2
-1
@@ -1,8 +1,9 @@
1
use crate::url_builder::{build_project_url, build_project_url_with_id};
2
+use network::environment::Environment;
3
use network::network::request;
4
use reqwest::Client;
5
use smbcloud_model::{error_codes::ErrorResponse, project::Project};
5
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6
+use smbcloud_networking::constants::SMB_USER_AGENT;
7
8
pub async fn get_project(
9
env: Environment,
crates/smbcloud-networking-project/src/crud_project_update.rs
+2
-1
@@ -1,8 +1,9 @@
1
use crate::url_builder::build_project_url_with_id;
2
+use network::environment::Environment;
3
use network::network::request;
4
use reqwest::Client;
5
use smbcloud_model::{error_codes::ErrorResponse, project::Project};
5
-use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6
+use smbcloud_networking::constants::SMB_USER_AGENT;
7
8
pub async fn update_project_description(
9
env: Environment,
crates/smbcloud-networking-project/src/url_builder.rs
+2
-1
@@ -1,4 +1,5 @@
1
-use smbcloud_networking::{environment::Environment, smb_base_url_builder};
1
+use network::environment::Environment;
2
+use smbcloud_networking::smb_base_url_builder;
3
4
// Private functions
5
crates/smbcloud-networking/Cargo.toml
+1
-12
@@ -21,16 +21,5 @@ categories = [
21
crate-type = ["cdylib", "rlib"]
22
23
[dependencies]
24
-anyhow = { workspace = true }
25
-async-trait = { workspace = true, optional = true }
26
-clap = { workspace = true, features = ["derive", "env"] }
27
-dirs = { workspace = true }
28
-home = { workspace = true }
29
-log = { workspace = true }
30
-maybe-async = { workspace = true, features = ["is_sync"] }
31
-reqwest = { workspace = true, features = ["json"] }
32
-serde = { workspace = true, features = ["derive"] }
33
-serde_json = { workspace = true }
34
-smbcloud-model = { workspace = true }
35
-thiserror = { workspace = true }
24
+network = { workspace = true }
25
url-builder = { workspace = true }
crates/smbcloud-networking/src/lib.rs
+1
-33
@@ -1,41 +1,9 @@
1
pub mod constants;
2
-pub mod environment;
2
4
-use anyhow::{anyhow, Result};
3
use constants::{SMB_CLIENT_ID, SMB_CLIENT_SECRET};
6
-use environment::Environment;
7
-use log::debug;
8
-use std::path::{Path, PathBuf};
4
+use network::environment::Environment;
5
use url_builder::URLBuilder;
6
11
-pub async fn get_smb_token(env: Environment) -> Result<String> {
12
- if let Some(path) = smb_token_file_path(env) {
13
- std::fs::read_to_string(path).map_err(|e| {
14
- debug!("Error while reading token: {}", &e);
15
- anyhow!("Error while reading token. Are you logged in?")
16
- })
17
- } else {
18
- Err(anyhow!("Failed to get home directory. Are you logged in?"))
19
- }
20
-}
21
-
22
-pub fn smb_token_file_path(env: Environment) -> Option<PathBuf> {
23
- match home::home_dir() {
24
- Some(home_path) => {
25
- let token_path = [&env.smb_dir(), "/token"].join("");
26
- let token_file = home_path.join(Path::new(&token_path));
27
- if token_file.exists() && token_file.is_file() {
28
- return Some(token_file);
29
- }
30
- None
31
- }
32
- None => {
33
- debug!("Failed to get home directory.");
34
- None
35
- }
36
- }
37
-}
38
-
7
pub fn smb_base_url_builder(env: Environment) -> URLBuilder {
8
let mut url_builder = URLBuilder::new();
9
url_builder