1use crate::prelude::{Client, Params};
2use std::error::Error;
3
4#[doc = "Parameters for the Earth API"]
5#[derive(Clone, Copy, Debug, PartialEq)]
6pub struct EarthParams<'p>
7{
8 #[doc = "Latitude of the location"]
9 pub lat: f64,
10 #[doc = "Longitude of the location"]
11 pub lon: f64,
12 #[doc = "Dimension of the image (Optional)"]
13 pub dim: Option<f64>,
14 #[doc = "Date of the image (Optional)"]
15 pub date: Option<&'p str>,
16 #[doc = "Include cloud score in the response (Optional)"]
17 pub cloud_score: Option<bool>,
18}
19
20impl<'p> Default for EarthParams<'p>
21{
22 fn default() -> Self
23 {
24 Self {
25 lat: 0.0,
26 lon: 0.0,
27 dim: None,
28 date: None,
29 cloud_score: None,
30 }
31 }
32}
33
34#[allow(missing_docs)]
35impl<'p> EarthParams<'p>
36{
37 pub fn new() -> Self { Self::default() }
38
39 pub fn lat(mut self, lat: f64) -> Self
40 {
41 self.lat = lat;
42 return self;
43 }
44
45 pub fn lon(mut self, lon: f64) -> Self
46 {
47 self.lon = lon;
48 return self;
49 }
50
51 pub fn dim(mut self, dim: f64) -> Self
52 {
53 self.dim = Some(dim);
54 return self;
55 }
56
57 pub fn date(mut self, date: &'p str) -> Self
58 {
59 self.date = Some(date);
60 return self;
61 }
62
63 pub fn cloud_score(mut self, cloud_score: bool) -> Self
64 {
65 self.cloud_score = Some(cloud_score);
66 return self;
67 }
68}
69
70impl<'p> Into<String> for EarthParams<'p>
71{
72 fn into(self) -> String
73 {
74 let mut params = String::new();
75 params.push_str(&format!("lat={}", self.lat));
76 params.push_str(&format!("&lon={}", self.lon));
77
78 if let Some(dim) = self.dim
79 {
80 params.push_str(&format!("&dim={}", dim));
81 }
82 if let Some(date) = self.date
83 {
84 params.push_str(&format!("&date={}", date));
85 }
86 if let Some(cloud_score) = self.cloud_score
87 {
88 params.push_str(&format!("&cloud_score={}", cloud_score));
89 }
90
91 return params;
92 }
93}
94
95impl<'p> Params for EarthParams<'p> {}
96
97#[allow(missing_docs)]
98#[derive(Clone, Debug)]
99pub struct Earth {}
100
101impl Default for Earth
102{
103 fn default() -> Self { Self {} }
104}
105
106#[allow(missing_docs)]
107impl Earth
108{
109 pub fn new() -> Self { return Self::default() }
110}
111
112impl<'p, PARA> Client<PARA> for Earth
113where
114 PARA: Params,
115{
116 const BASE_URL: &'static str = "https://api.nasa.gov/planetary/earth/imagery";
117 type Response = serde_json::Value;
118
119 fn get(&self, params: PARA) -> Result<Self::Response, Box<dyn Error>>
120 {
121 let base_url = <Earth as Client<PARA>>::BASE_URL;
122 let url_with_params = format!("{}?{}", base_url, params.into());
123 let url_with_key = crate::prelude::keys::include(&url_with_params)?;
124 let response = ureq::get(&url_with_key).call()?;
125 let json = serde_json::json!(response.into_string()?);
126 return Ok(json);
127 }
128}
129
130#[cfg(test)]
131mod earth_tests
132{
133 use super::*;
134
135 #[test]
136 fn test_earth()
137 {
138 let earth = Earth::default();
139 let params = EarthParams::default();
140 let response = earth.get(params);
141 match response
142 {
143 Ok(json) => println!("{:#?}", json),
144 Err(e) =>
145 {
146 println!("{:#?}", e);
147 panic!()
148 }
149 }
150 }
151}