summaryrefslogtreecommitdiffstats
path: root/src/client.rs
blob: 72490984319b2ad917f3d6039c28bfb8dbd786fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::io::Write;
use std::str::FromStr;

use anyhow::Context;
use anyhow::Error;
use anyhow::Result;
use anyhow::anyhow;
use itertools::Itertools;

mod config;
mod cli;
mod schema;

use fss::fss_client::FssClient;
use fss::VersionRequest;
use fss::IndexFileRequest;
use fss::SearchQueryRequest;

mod fss {
    tonic::include_proto!("fss");
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = crate::cli::client_app();
    let matches = cli.get_matches();
    let _ = env_logger::try_init()?;
    let mut config = ::config::Config::default();
    {
        let xdg = xdg::BaseDirectories::with_prefix("fss")?;
        let xdg_config = xdg.find_config_file("config.toml")
            .ok_or_else(|| anyhow!("No configuration file found with XDG: {}", xdg.get_config_home().display()))?;

        log::debug!("Configuration file found with XDG: {}", xdg_config.display());
        config.merge(::config::File::from(xdg_config).required(false))
            .context("Failed to load config.toml from XDG configuration directory")?;
    }
    let config = config.try_into::<crate::config::Config>()?;
    let server_addr = matches.value_of("server_addr").unwrap_or_else(|| config.server_addr());
    let server_port = matches.value_of("server_port").map(usize::from_str).unwrap_or_else(|| Ok(*config.server_port()))?;
    let addr = format!("http://{}:{}", server_addr, server_port);

    let mut client = FssClient::connect(addr).await?;
    let request = tonic::Request::new(VersionRequest { });
    let _response = client.get_version(request).await?;

    match matches.subcommand() {
        ("index", Some(mtch)) => {
            let path = mtch.value_of("file").map(String::from).unwrap(); // safe by clap
            let request = tonic::Request::new(IndexFileRequest { path });
            let response = client.index_file(request).await?;

            if response.get_ref().error {
                Err(anyhow!("Error indexing file"))
            } else {
                Ok(())
            }
        },

        ("search", Some(mtch)) => {
            let query = mtch.values_of("term")
                .unwrap() // safe by clap
                .join(" ");

            let request = tonic::Request::new(SearchQueryRequest { query });
            let response = client.search_query(request).await?;
            let mut output = std::io::stdout();

            if response.get_ref().success {
                response.get_ref()
                    .pathes
                    .iter()
                    .map(|pb| writeln!(output, "{}", pb).map_err(Error::from))
                    .collect::<Result<Vec<_>>>()
                    .map(|_| ())
            } else {
                Err(anyhow!("Failed to search"))
            }
        },

        (_other, _) => {
            unimplemented!()
        },
    }
}