1use crate::api::{APIClient, API, BASE_URL};
2use crate::api_types::{compile, download, execute, fmt, share};
3use crate::input;
4use crate::printer::Printer;
5use std::collections::HashMap;
6use url::{ParseError, Url};
7
8pub struct Handler {
9 api_cli: APIClient,
11 printer: Printer,
12}
13
14impl Handler {
15 pub fn new() -> Handler {
16 Handler {
17 api_cli: APIClient::new(),
18 printer: Printer::new(),
19 }
20 }
21
22 pub fn run(&mut self, input: input::RunInput) -> Result<(), Box<dyn std::error::Error>> {
23 let code = input::code_from_path(&input.file_path)?;
24
25 let request = execute::Request {
27 crate_type: "bin".to_string(),
28 tests: false,
29 mode: input.mode,
30 channel: input.channel,
31 edition: input.edition,
32 backtrace: input.backtrace,
33 code: code,
34 };
35
36 let resp = self.api_cli.execute(request)?;
37
38 self.printer.print_run(resp)?;
50
51 Ok(())
52 }
53
54 pub fn fmt(&mut self, input: input::FmtInput) -> Result<(), Box<dyn std::error::Error>> {
55 let code = input::code_from_path(&input.file_path)?;
56
57 let request = fmt::Request {
58 edition: input.edition,
59 code: code,
60 };
61
62 let resp = self.api_cli.fmt(request)?;
63
64 self.printer.print_fmt(resp)?;
65
66 Ok(())
67 }
68
69 pub fn share(&mut self, input: input::ShareInput) -> Result<(), Box<dyn std::error::Error>> {
70 let code = input::code_from_path(&input.file_path)?;
71
72 let request = share::Request { code: code };
73
74 let resp = self.api_cli.share(request)?;
75
76 self.printer.print_share(resp)?;
77
78 Ok(())
79 }
80
81 pub fn download(
82 &mut self,
83 input: input::DownloadInput,
84 ) -> Result<(), Box<dyn std::error::Error>> {
85 let id = pick_id_from(input.id_or_url)?;
86
87 let request = download::Request { id: id };
88
89 let resp = self.api_cli.download(request)?;
90
91 self.printer.print_download(resp)?;
92
93 Ok(())
94 }
95}
96
97fn pick_id_from(id_or_url: String) -> Result<String, Box<std::error::Error>> {
99 if id_or_url.starts_with(BASE_URL) {
100 let url = Url::parse(&id_or_url);
103 if let Ok(url) = url {
104 let hash_query: HashMap<_, _> = url.query_pairs().into_owned().collect();
105
106 match hash_query.get("gist") {
107 Some(id) => return Ok(id.to_string()),
108 None => return Ok("".to_string()),
109 };
110 } else {
111 return Ok("".to_string());
112 }
113 } else {
114 Ok(id_or_url)
116 }
117}