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!()
},
}
}
|