dizhen 0.1.1

Library to retrieve seismic data
Documentation
use {
	crate::{Event, DateTimeUtc, Result},
};

pub mod cenc;
pub mod usgs;

pub use cenc::CENCSource;
pub use usgs::USGSSource;

pub type SourceId = &'static str;

pub trait Source {
	/// "Latest" here is defined as having data of at least 1 hour from now,
	/// usually above M3.0.
	fn get_latest(&self) -> Result<Vec<Event>>;

	fn query(&self) -> QueryPlan where Self: Sized {
		QueryPlan::with_source(self)
	}
	fn run_query(&self, query: &QueryPlan) -> Result<Vec<Event>>;
}

pub trait SourceInfo {
	const SOURCE_ID: SourceId;
	const LATEST_API_URL: &'static str;
	const HISTORY_API_URL: &'static str;
}

pub struct QueryPlan<'q> {
	source: &'q dyn Source,

	since: Option<&'q DateTimeUtc>,
	until: Option<&'q DateTimeUtc>,

	min_lon: Option<f64>,
	max_lon: Option<f64>,
	min_lat: Option<f64>,
	max_lat: Option<f64>,
	min_depth: Option<f64>,
	max_depth: Option<f64>,
	min_mag: Option<f64>,
	max_mag: Option<f64>,

	page: u32,
	page_size: u32,

}

impl<'q> QueryPlan<'q> {
	pub fn with_source<S: Source>(source: &'q S) -> Self {
		Self{
			source,
			since: None,
			until: None,
			min_lon: None,
			max_lon: None,
			min_lat: None,
			max_lat: None,
			min_depth: None,
			max_depth: None,
			min_mag: None,
			max_mag: None,
			page: 1,
			page_size: 100,
		}
	}

	pub fn run(self) -> Result<Vec<Event>> {
		self.source.run_query(&self)
	}

	pub fn since(mut self, time: &'q DateTimeUtc) -> Self { self.since = Some(time); self }
	pub fn until(mut self, time: &'q DateTimeUtc) -> Self { self.until = Some(time); self }
	pub fn min_lon(mut self, value: f64) -> Self { self.min_lon = Some(value); self }
	pub fn max_lon(mut self, value: f64) -> Self { self.max_lon = Some(value); self }
	pub fn min_lat(mut self, value: f64) -> Self { self.min_lat = Some(value); self }
	pub fn max_lat(mut self, value: f64) -> Self { self.max_lat = Some(value); self }
	pub fn min_depth(mut self, value: f64) -> Self { self.min_depth = Some(value); self }
	pub fn max_depth(mut self, value: f64) -> Self { self.max_depth = Some(value); self }
	pub fn min_mag(mut self, value: f64) -> Self { self.min_mag = Some(value); self }
	pub fn max_mag(mut self, value: f64) -> Self { self.max_mag = Some(value); self }
	pub fn page(mut self, value: u32) -> Self { self.page = value; self }
	/// Not all sources use this, e.g CENC ignores it.
	pub fn page_size(mut self, value: u32) -> Self { self.page_size = value; self }
}

fn opt_to_str<T: ToString>(opt: Option<T>) -> String {
	opt.map(|v| v.to_string()).unwrap_or_else(|| "".to_string())
}