1#![warn(missing_docs, clippy::unwrap_used)]
5
6pub mod args;
8pub mod config;
10pub mod error;
12pub mod upload;
14
15use crate::args::Args;
16use crate::config::Config;
17use crate::error::{Error, Result};
18use crate::upload::Uploader;
19use colored::Colorize;
20use std::fs;
21use std::io::IsTerminal;
22use std::io::{self, Read};
23
24const CONFIG_FILE: &str = "config.toml";
26
27pub fn run(args: Args) -> Result<()> {
29 let mut config = Config::default();
30 if let Some(ref config_path) = args.config {
31 config = toml::from_str(&fs::read_to_string(config_path)?)?
32 } else {
33 for path in [
34 dirs_next::home_dir().map(|p| p.join(".rustypaste").join(CONFIG_FILE)),
35 dirs_next::config_dir().map(|p| p.join("rustypaste").join(CONFIG_FILE)),
36 ]
37 .iter()
38 .filter_map(|v| v.as_ref())
39 {
40 if path.exists() {
41 config = toml::from_str(&fs::read_to_string(path)?)?;
42 break;
43 }
44 }
45 }
46 config.parse_token_files();
47 config.update_from_args(&args);
48 if config.server.address.is_empty() {
49 return Err(Error::NoServerAddressError);
50 }
51
52 let uploader = Uploader::new(&config);
53 if args.print_server_version {
54 println!("rustypaste-server {}", uploader.retrieve_version()?.trim());
55 return Ok(());
56 }
57
58 if args.list_files {
59 let prettify = args.prettify
60 || config
61 .style
62 .as_ref()
63 .map(|style| style.prettify)
64 .unwrap_or(false);
65 uploader.retrieve_list(&mut io::stdout(), prettify)?;
66 return Ok(());
67 }
68
69 let mut results = Vec::new();
70 if let Some(ref url) = args.url {
71 results.push(uploader.upload_url(url));
72 } else if let Some(ref remote_url) = args.remote {
73 results.push(uploader.upload_remote_url(remote_url));
74 } else if !std::io::stdin().is_terminal() || args.files.contains(&String::from("-")) {
75 let mut buffer = Vec::new();
76 let mut stdin = io::stdin();
77 stdin.read_to_end(&mut buffer)?;
78 results.push(uploader.upload_stream(&*buffer));
79 } else {
80 for file in args.files.iter() {
81 if !args.delete {
82 results.push(uploader.upload_file(file))
83 } else {
84 results.push(uploader.delete_file(file))
85 }
86 }
87 }
88 let prettify = args.prettify
89 || config
90 .style
91 .as_ref()
92 .map(|style| style.prettify)
93 .unwrap_or(false);
94 let format_padding = prettify
95 .then(|| results.iter().map(|v| v.0.len()).max())
96 .flatten()
97 .unwrap_or(1);
98 for (data, result) in results.iter().map(|v| (v.0, v.1.as_ref())) {
99 let data = if prettify {
100 format!(
101 "{:p$} {} ",
102 data,
103 if result.is_ok() {
104 "=>".green().bold()
105 } else {
106 "=>".red().bold()
107 },
108 p = format_padding,
109 )
110 } else {
111 String::new()
112 };
113 match result {
114 Ok(url) => println!("{}{}", data, url.trim()),
115 Err(e) => eprintln!("{data}{e}"),
116 }
117 }
118
119 Ok(())
120}