1use crate::error::UnitxError;
2
3pub fn validate_temperature_value(value: f64) -> Result<(), UnitxError> {
4 if !value.is_finite() {
5 return Err(UnitxError::ValidationError(
6 "Temperature must be finite".to_string(),
7 ));
8 }
9 if value < -273.15 {
10 return Err(UnitxError::ValidationError(
11 "Temperature below absolute zero (-273.15°C)".to_string(),
12 ));
13 }
14 if value > 1e6 {
15 return Err(UnitxError::ValidationError(
16 "Temperature too high (max 1,000,000)".to_string(),
17 ));
18 }
19 Ok(())
20}
21
22pub fn validate_distance_value(value: f64) -> Result<(), UnitxError> {
23 if !value.is_finite() {
24 return Err(UnitxError::ValidationError(
25 "Distance must be finite".to_string(),
26 ));
27 }
28 if value < 0.0 {
29 return Err(UnitxError::ValidationError(
30 "Distance cannot be negative".to_string(),
31 ));
32 }
33 if value > 1e12 {
34 return Err(UnitxError::ValidationError(
35 "Distance too large (max 1 trillion)".to_string(),
36 ));
37 }
38 Ok(())
39}
40
41pub fn validate_currency_value(value: &str) -> Result<(), UnitxError> {
42 use rust_decimal::Decimal;
43 use std::str::FromStr;
44
45 if value.is_empty() {
46 return Err(UnitxError::ValidationError(
47 "Currency amount cannot be empty".to_string(),
48 ));
49 }
50
51 if value.len() > 20 {
52 return Err(UnitxError::ValidationError(
53 "Currency amount too long (max 20 chars)".to_string(),
54 ));
55 }
56
57 match Decimal::from_str(value) {
58 Ok(decimal) => {
59 if decimal < Decimal::ZERO {
60 Err(UnitxError::ValidationError(
61 "Currency amount cannot be negative".to_string(),
62 ))
63 } else if decimal > Decimal::from(1_000_000_000i64) {
64 Err(UnitxError::ValidationError(
65 "Currency amount too large (max 1 billion)".to_string(),
66 ))
67 } else {
68 Ok(())
69 }
70 }
71 Err(_) => Err(UnitxError::ValidationError(
72 "Invalid currency amount format".to_string(),
73 )),
74 }
75}
76
77pub fn validate_unit_string(unit: &str, category: &str) -> Result<(), UnitxError> {
78 if unit.is_empty() {
79 return Err(UnitxError::ValidationError(format!(
80 "{} unit cannot be empty",
81 category
82 )));
83 }
84 if unit.len() > 10 {
85 return Err(UnitxError::ValidationError(format!(
86 "{} unit too long (max 10 chars)",
87 category
88 )));
89 }
90 if !unit.chars().all(|c| c.is_ascii_alphabetic()) {
91 return Err(UnitxError::ValidationError(format!(
92 "{} unit must contain only letters",
93 category
94 )));
95 }
96 Ok(())
97}