summaryrefslogtreecommitdiffstats
path: root/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/client.rs b/src/client.rs
new file mode 100644
index 0000000..7249098
--- /dev/null
+++ b/src/client.rs
@@ -0,0 +1,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!()
+ },
+ }
+}