1use config::{FileFormat, Format, Map, Source, Value};
2use std::fmt::Debug;
3
4pub type File<T, F> = config::File<T, F>;
5pub type Config = config::Config;
6pub type Environment = config::Environment;
7pub type ConfigError = config::ConfigError;
8pub type HeaderMap = reqwest::header::HeaderMap;
9
10#[derive(Debug, Clone)]
12pub enum HttpMethod {
13 Get,
14 Post,
15}
16impl Default for HttpMethod {
17 fn default() -> Self {
18 HttpMethod::Get
19 }
20}
21
22#[derive(Debug, Clone)]
24pub struct Http {
25 url: String,
26 method: HttpMethod,
27 format: FileFormat,
28}
29
30impl Http {
31 pub fn new<S: AsRef<str>>(url: S, format: FileFormat, method: HttpMethod) -> Self {
32 Http {
33 url: url.as_ref().to_string(),
34 format,
35 method,
36 }
37 }
38 pub fn with(url: &str, format: &str, method: &str) -> Self {
39 Http {
40 url: url.to_string(),
41 format: Http::convert_format(format),
42 method: Http::convert_method(method),
43 }
44 }
45
46 fn convert_format(format: &str) -> FileFormat {
47 match format {
48 "toml" => FileFormat::Toml,
49 "json" => FileFormat::Json,
50 "yaml" => FileFormat::Yaml,
51 "ini" => FileFormat::Ini,
52 "ron" => FileFormat::Ron,
53 "json5" => FileFormat::Json5,
54 _ => unreachable!("不支持格式"),
55 }
56 }
57
58 fn convert_method(method: &str) -> HttpMethod {
59 match method {
60 "get" => HttpMethod::Get,
61 "post" => HttpMethod::Post,
62 _ => unreachable!("没有启用特性"),
63 }
64 }
65}
66
67impl Source for Http {
68 fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
69 Box::new((*self).clone())
70 }
71
72 fn collect(&self) -> Result<Map<String, Value>, ConfigError> {
73 let client = match reqwest::blocking::Client::builder().build() {
74 Ok(client) => client,
75 Err(e) => return Err(ConfigError::Message(e.to_string())),
76 };
77
78 let response = match self.method {
79 HttpMethod::Get => client.get(&self.url).send(),
80 HttpMethod::Post => client.post(&self.url).send(),
81 };
82
83 let response = match response {
84 Ok(response) => response,
85 Err(e) => return Err(ConfigError::Message(e.to_string())),
86 };
87
88 let content = match response.text() {
89 Ok(content) => content,
90 Err(e) => return Err(ConfigError::Message(e.to_string())),
91 };
92
93 let format = self.format;
94
95 format
96 .parse(None, &content)
97 .map_err(|cause| ConfigError::Message(cause.to_string()))
98 }
99}