use crate::{error::Hyper3dError, types::DEFAULT_CONDITION_MODE}; pub(crate) fn normalize_required_text( value: &str, field: &'static str, max_chars: usize, ) -> Result { let normalized = value.trim().to_string(); if normalized.is_empty() { return Err(Hyper3dError::invalid_request( Some(field), format!("{field} 不能为空"), )); } if normalized.chars().count() > max_chars { return Err(Hyper3dError::invalid_request( Some(field), format!("{field} 超过 {} 字符", max_chars), )); } Ok(normalized) } pub(crate) fn normalize_optional_limited_text( value: Option<&str>, max_chars: usize, ) -> Result, Hyper3dError> { let Some(normalized) = value.map(str::trim).filter(|value| !value.is_empty()) else { return Ok(None); }; if normalized.chars().count() > max_chars { return Err(Hyper3dError::invalid_request( None, format!("文本超过 {} 字符", max_chars), )); } Ok(Some(normalized.to_string())) } pub(crate) fn normalize_required_opaque_text( value: &str, field: &'static str, ) -> Result { let normalized = value.trim().to_string(); if normalized.is_empty() { return Err(Hyper3dError::invalid_request( Some(field), format!("{field} 不能为空"), )); } Ok(normalized) } pub(crate) fn normalize_enum( value: Option<&str>, default_value: &str, allowed_values: &[&str], field: &'static str, ) -> Result { let value = value .map(str::trim) .filter(|value| !value.is_empty()) .unwrap_or(default_value); if let Some(allowed) = allowed_values .iter() .find(|allowed| allowed.eq_ignore_ascii_case(value)) { return Ok((*allowed).to_string()); } Err(Hyper3dError::invalid_request_allowed( field, format!("{} 取值非法", field), allowed_values, )) } pub(crate) fn normalize_condition_mode(value: Option<&str>) -> Result { normalize_enum( value, DEFAULT_CONDITION_MODE, &["concat", "fuse"], "conditionMode", ) } pub(crate) fn normalize_addons(values: Vec) -> Result, Hyper3dError> { let mut addons = Vec::new(); for value in values { let value = value.trim(); if value.is_empty() { continue; } if value != "HighPack" { return Err(Hyper3dError::invalid_request( Some("addons"), "addons 首版只支持 HighPack", )); } if !addons.iter().any(|addon| addon == value) { addons.push(value.to_string()); } } Ok(addons) } pub(crate) fn normalize_bbox_condition( value: Option>, ) -> Result>, Hyper3dError> { let Some(value) = value else { return Ok(None); }; if value.len() != 3 || value.iter().any(|item| !item.is_finite() || *item <= 0.0) { return Err(Hyper3dError::invalid_request( Some("bboxCondition"), "bboxCondition 必须包含 3 个正数", )); } Ok(Some(value)) }