tvscreener/mcp/
resolve.rs1use crate::error::{Result, TvscreenerError};
7use crate::field::Asset;
8
9pub use crate::resolve::{
10 apply_stock_index_markets, parse_csv_tokens, resolve_country_wires, resolve_exchange_wires,
11 resolve_index_wires, resolve_industry_wires, resolve_market_wires, resolve_sector_wires,
12};
13
14#[must_use]
18pub fn parse_f64_range(raw: Option<&str>) -> (Option<f64>, Option<f64>) {
19 let Some(raw) = raw.map(str::trim).filter(|s| !s.is_empty()) else {
20 return (None, None);
21 };
22 let mut parts = raw.splitn(2, ',');
23 let min = parts
24 .next()
25 .map(str::trim)
26 .filter(|s| !s.is_empty())
27 .and_then(|s| s.parse().ok());
28 let max = parts
29 .next()
30 .map(str::trim)
31 .filter(|s| !s.is_empty())
32 .and_then(|s| s.parse().ok());
33 (min, max)
34}
35
36pub fn parse_asset(asset_type: &str) -> Result<Asset> {
42 Asset::parse(asset_type.trim().to_ascii_lowercase().as_str()).ok_or_else(|| {
43 TvscreenerError::InvalidRequest(format!(
44 "unknown asset_type `{asset_type}` (use stock|crypto|forex|bond|futures|coin)"
45 ))
46 })
47}
48
49#[cfg(test)]
50mod tests {
51 use super::parse_f64_range;
52
53 #[test]
54 fn parse_f64_range_sides() {
55 assert_eq!(parse_f64_range(None), (None, None));
56 assert_eq!(parse_f64_range(Some("")), (None, None));
57 assert_eq!(parse_f64_range(Some("10,20")), (Some(10.0), Some(20.0)));
58 assert_eq!(parse_f64_range(Some("10,")), (Some(10.0), None));
59 assert_eq!(parse_f64_range(Some(",20")), (None, Some(20.0)));
60 assert_eq!(parse_f64_range(Some("x,20")), (None, Some(20.0)));
61 assert_eq!(parse_f64_range(Some("10,y")), (Some(10.0), None));
62 }
63}