Skip to main content

atsh_lib/
lib.rs

1mod config;
2mod connection;
3mod storage;
4
5pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
6
7pub mod atsh {
8    use std::io::{Error, ErrorKind};
9    use std::path::Path;
10    use tracing::debug;
11
12    use crate::connection::Remotes;
13    use crate::storage::log::setup_logging;
14
15    // export the objects to the outside
16    pub use crate::config::CONFIG;
17    pub use crate::connection::Remote;
18    pub use crate::Result;
19
20    pub fn initialize(work_dir: Option<impl AsRef<Path>>) -> Result<()> {
21        if let Some(p) = work_dir {
22            CONFIG.set_work_dir(p)?;
23        }
24        let w = CONFIG.get_work_dir();
25        setup_logging(w)?;
26        debug!("success initialize at {:?}", w);
27        Ok(())
28    }
29
30    pub fn add(
31        user: &str,
32        password: &str,
33        ip: &str,
34        port: u16,
35        name: &Option<impl AsRef<str>>,
36        note: &Option<impl AsRef<str>>,
37    ) -> Result<usize> {
38        Remotes::add(user, password, ip, port, name, note)
39    }
40
41    pub fn add_remote(remote: &Remote) -> Result<usize> {
42        add(
43            &remote.user,
44            &remote.password,
45            &remote.ip,
46            remote.port,
47            &remote.name,
48            &remote.note,
49        )
50    }
51
52    pub async fn remove(index: &Vec<usize>) -> Result<usize> {
53        Remotes::delete(index).await
54    }
55
56    pub fn get(index: usize) -> Result<Option<Remote>> {
57        Remotes::get(index)
58    }
59
60    pub fn try_get(index: usize) -> Result<Remote> {
61        Remotes::try_get(index)
62    }
63
64    pub fn get_all() -> Result<Vec<Remote>> {
65        let remotes = Remotes::get_all()?;
66        Ok(remotes.0)
67    }
68
69    pub fn pprint(all: bool) -> Result<()> {
70        let remotes = Remotes::get_all()?;
71        remotes.pprint(all);
72        Ok(())
73    }
74
75    // pub fn list(all: bool) -> Result<()> {
76    //     if all {
77    //         Remotes::list_all()
78    //     } else {
79    //         Remotes::list()
80    //     }
81    // }
82
83    // auth params means try auth against the server
84    pub async fn login(index: usize, auth: bool) -> Result<()> {
85        let remote = Remotes::try_get(index)?;
86        remote.login(auth).await
87    }
88
89    // #[deprecated(
90    //     since = "0.1.2",
91    //     note = "This function is not clearly expressed; use `upload/download` instead."
92    // )]
93    // pub fn copy(index: usize, path: &str) -> Result<()> {
94    //     let paths = path.split('=').collect::<Vec<&str>>();
95    //     if paths.len() != 2 {
96    //         return Err(Error::new(
97    //             ErrorKind::InvalidInput,
98    //             "path format error, like `from=to`",
99    //         ));
100    //     }
101    //     let remote = Remotes::try_get(index)?;
102    //     if std::path::PathBuf::from(paths[0]).exists() {
103    //         remote.upload(paths[0], paths[1])
104    //     } else {
105    //         remote.download(paths[0], paths[1])
106    //     }
107    // }
108
109    pub async fn upload(index: usize, path: &Vec<impl AsRef<str>>) -> Result<()> {
110        (path.len() == 2).then_some(()).ok_or_else(|| {
111            Box::new(std::io::Error::new(
112                std::io::ErrorKind::InvalidInput,
113                "path format error, like `upload -p /local/path /remote/path`",
114            ))
115        })?;
116
117        let (local, remote) = (path[0].as_ref(), path[1].as_ref());
118        Path::new(local).exists().then_some(()).ok_or_else(|| {
119            Box::new(Error::new(ErrorKind::NotFound, "the upload file not found"))
120        })?;
121
122        Remotes::try_get(index)?.upload(local, remote).await
123    }
124
125    pub async fn download(index: usize, path: &Vec<impl AsRef<str>>) -> Result<()> {
126        (path.len() == 2).then_some(()).ok_or_else(|| {
127            Box::new(std::io::Error::new(
128                std::io::ErrorKind::InvalidInput,
129                "path format error, like `download -p /remote/path /local/path`",
130            ))
131        })?;
132
133        let (remote, local) = (path[0].as_ref(), path[1].as_ref());
134        Remotes::try_get(index)?.download(remote, local).await
135    }
136}