use crate::error::{EdfError, Result};
pub fn is_integer_number(s: &str) -> bool {
if s.is_empty() {
return false;
}
let s = s.trim();
if s.is_empty() {
return false;
}
s.chars().next().map_or(false, |first| first == '+' || first == '-' || first.is_ascii_digit()) &&
s.chars().skip(if s.starts_with('+') || s.starts_with('-') { 1 } else { 0 })
.all(|c| c.is_ascii_digit() || c == ' ') &&
s.chars().any(|c| c.is_ascii_digit())
}
pub fn is_number(s: &str) -> bool {
if s.is_empty() {
return false;
}
let s = s.trim();
if s.is_empty() {
return false;
}
s.parse::<f64>().is_ok()
}
pub fn parse_edf_time(s: &str) -> Result<i64> {
let s = s.trim();
if s.is_empty() {
return Err(EdfError::InvalidFormat("Empty time string".to_string()));
}
let (negative, s) = if s.starts_with('-') {
(true, &s[1..])
} else if s.starts_with('+') {
(false, &s[1..])
} else {
(false, s)
};
let mut value = 0i64;
if let Some(dot_pos) = s.find('.') {
let integer_part = &s[..dot_pos];
let decimal_part = &s[dot_pos + 1..];
if !integer_part.is_empty() {
value += integer_part.parse::<i64>()
.map_err(|_| EdfError::InvalidFormat("Invalid integer part".to_string()))?
* crate::EDFLIB_TIME_DIMENSION;
}
if !decimal_part.is_empty() {
let decimal_str = if decimal_part.len() > 7 {
&decimal_part[..7]
} else {
decimal_part
};
let decimal_value = decimal_str.parse::<i64>()
.map_err(|_| EdfError::InvalidFormat("Invalid decimal part".to_string()))?;
let scale = 10i64.pow(7 - decimal_str.len() as u32);
value += decimal_value * scale;
}
} else {
value = s.parse::<i64>()
.map_err(|_| EdfError::InvalidFormat("Invalid integer".to_string()))?
* crate::EDFLIB_TIME_DIMENSION;
}
if negative {
value = -value;
}
Ok(value)
}
pub fn trim_padding_spaces(s: &mut String) {
let trimmed = s.trim().to_string();
s.clear();
s.push_str(&trimmed);
}
pub fn atoi_nonlocalized(s: &str) -> i32 {
let s = s.trim();
if s.is_empty() {
return 0;
}
s.parse().unwrap_or(0)
}
pub fn atof_nonlocalized(s: &str) -> f64 {
let s = s.trim();
if s.is_empty() {
return 0.0;
}
s.parse().unwrap_or(0.0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_integer_number() {
assert!(is_integer_number("123"));
assert!(is_integer_number("-456"));
assert!(is_integer_number("+789"));
assert!(is_integer_number("0"));
assert!(!is_integer_number("12.34"));
assert!(!is_integer_number("abc"));
assert!(!is_integer_number(""));
}
#[test]
fn test_parse_edf_time() {
assert_eq!(parse_edf_time("1").unwrap(), 10_000_000);
assert_eq!(parse_edf_time("1.5").unwrap(), 15_000_000);
assert_eq!(parse_edf_time("-2.5").unwrap(), -25_000_000);
assert_eq!(parse_edf_time("+0.0000001").unwrap(), 1);
}
}