Files
Genarrative/server-rs/crates/platform-hyper3d/src/request/normalize.rs
2026-05-26 13:18:13 +08:00

120 lines
3.3 KiB
Rust

use crate::{error::Hyper3dError, types::DEFAULT_CONDITION_MODE};
pub(crate) fn normalize_required_text(
value: &str,
field: &'static str,
max_chars: usize,
) -> Result<String, Hyper3dError> {
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<Option<String>, 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<String, Hyper3dError> {
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<String, Hyper3dError> {
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<String, Hyper3dError> {
normalize_enum(
value,
DEFAULT_CONDITION_MODE,
&["concat", "fuse"],
"conditionMode",
)
}
pub(crate) fn normalize_addons(values: Vec<String>) -> Result<Vec<String>, 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<Vec<f32>>,
) -> Result<Option<Vec<f32>>, 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))
}