1use std::process::Command;
2
3use crate::common::{is_in_path, tilde, SSHFS_EXECUTABLE};
4use crate::io::{command_with_path, execute_and_capture_output_with_path};
5use crate::{log_info, log_line};
6
7pub struct Remote {
10 pub username: String,
11 pub hostname: String,
12 pub remote_path: String,
13 pub local_path: String,
14 pub current_path: String,
15 pub port: String,
16}
17
18impl Remote {
19 pub fn from_input(input: String, current_path: &str) -> Option<Self> {
24 if !is_in_path(SSHFS_EXECUTABLE) {
25 log_info!("{SSHFS_EXECUTABLE} isn't in path");
26 return None;
27 }
28
29 Self::parse_remote_args(input, current_path)
30 }
31
32 fn parse_remote_args(input: String, current_path: &str) -> Option<Self> {
33 let user_host_port_remotepath_localpath: Vec<&str> = input.trim().split(' ').collect();
34 let number_of_args = user_host_port_remotepath_localpath.len();
35 if number_of_args != 3 && number_of_args != 4 {
36 log_info!(
37 "Wrong number of parameters for {SSHFS_EXECUTABLE}, expected 3 or 4, got {number_of_args}",
38 );
39 return None;
40 };
41
42 let (username, host_port, remote_path) = (
43 user_host_port_remotepath_localpath[0],
44 user_host_port_remotepath_localpath[1],
45 user_host_port_remotepath_localpath[2],
46 );
47
48 let host_port_splitted: Vec<&str> = host_port.trim().split(':').collect();
49 let hostname = host_port_splitted[0];
50 let port = if host_port_splitted.len() == 1 {
51 "22"
52 } else {
53 host_port_splitted[1]
54 };
55
56 let local_path = if number_of_args == 3 {
57 current_path
58 } else {
59 &tilde(user_host_port_remotepath_localpath[3])
60 };
61 Some(Self {
62 username: username.to_owned(),
63 hostname: hostname.to_owned(),
64 remote_path: remote_path.to_owned(),
65 current_path: current_path.to_owned(),
66 local_path: local_path.to_owned(),
67 port: port.to_owned(),
68 })
69 }
70
71 pub fn command(&self) -> Command {
74 let first_arg = format!(
75 "{username}@{hostname}:{remote_path}",
76 username = self.username,
77 hostname = self.hostname,
78 remote_path = self.remote_path
79 );
80 command_with_path(
81 SSHFS_EXECUTABLE,
82 &self.current_path,
83 &[&first_arg, &self.local_path, "-p", &self.port],
84 )
85 }
86
87 pub fn mount(&self) {
92 let first_arg = format!(
93 "{username}@{hostname}:{remote_path}",
94 username = self.username,
95 hostname = self.hostname,
96 remote_path = self.remote_path
97 );
98 let output = execute_and_capture_output_with_path(
99 SSHFS_EXECUTABLE,
100 &self.current_path,
101 &[&first_arg, &self.local_path, "-p", &self.port],
102 );
103 log_info!("{SSHFS_EXECUTABLE} {first_arg} output {output:?}");
104 log_line!("{SSHFS_EXECUTABLE} {first_arg} output {output:?}");
105 }
106}