From 155bf0b57a9d718fe6ba38be9da2a29df0000337 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Thu, 25 Dec 2025 17:10:27 +0800 Subject: [PATCH] Fix psb output float number with unneccery data --- src/ext/psb.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/ext/psb.rs b/src/ext/psb.rs index 3ce74ff..dcf668f 100644 --- a/src/ext/psb.rs +++ b/src/ext/psb.rs @@ -11,6 +11,7 @@ use emote_psb::types::string::*; use emote_psb::types::*; #[cfg(feature = "json")] use json::JsonValue; +use json::number::Number; use serde::ser::SerializeStruct; use serde::{Deserialize, Serialize}; use std::cmp::PartialEq; @@ -18,6 +19,48 @@ use std::collections::{BTreeMap, HashMap}; use std::io::{Read, Seek}; use std::ops::{Index, IndexMut}; +fn f32_to_number(x: f32) -> Number { + if !x.is_finite() { + return Number::from_parts(true, 0, 0); + } + + let s = format!("{}", x); + + if s.contains('e') || s.contains('E') { + let value = x as f64; + return if value >= 0.0 { + Number::from(value) + } else { + Number::from(value) + }; + } + + let positive = !s.starts_with('-'); + let s = s.trim_start_matches('-'); + + let parts: Vec<&str> = s.split('.').collect(); + + if parts.len() == 1 { + let mantissa: u64 = parts[0].parse().unwrap_or(0); + Number::from_parts(positive, mantissa, 0) + } else { + let int_part = parts[0]; + let frac_part = parts[1].trim_end_matches('0'); // 去除尾部的0 + + if frac_part.is_empty() { + // 没有实际小数部分 + let mantissa: u64 = int_part.parse().unwrap_or(0); + Number::from_parts(positive, mantissa, 0) + } else { + let combined = format!("{}{}", int_part, frac_part); + let mantissa: u64 = combined.parse().unwrap_or(0); + let exponent: i16 = -(frac_part.len() as i16); + + Number::from_parts(positive, mantissa, exponent) + } + } +} + const NONE: PsbValueFixed = PsbValueFixed::None; #[derive(Debug, Serialize, Deserialize)] @@ -361,7 +404,7 @@ impl PsbValueFixed { PsbValueFixed::Bool(b) => Some(JsonValue::Boolean(*b)), PsbValueFixed::Number(n) => match n { PsbNumber::Integer(i) => Some(JsonValue::Number((*i).into())), - PsbNumber::Float(f) => Some(JsonValue::Number((*f).into())), + PsbNumber::Float(f) => Some(JsonValue::Number(f32_to_number(*f))), PsbNumber::Double(d) => Some(JsonValue::Number((*d).into())), }, PsbValueFixed::String(s) => Some(JsonValue::String(s.string().to_owned())), @@ -1223,3 +1266,14 @@ impl PsbReaderExt for PsbReader { .map_err(|e| anyhow::anyhow!("Failed to load PSB: {:?}", e))?) } } + +#[cfg(feature = "json")] +#[test] +fn test_f32_to_json() { + let num = PsbValueFixed::Number(PsbNumber::Float(3.03)); + let json_value = num.to_json().unwrap(); + assert_eq!(json_value.to_string(), "3.03"); + let num = PsbValueFixed::Number(PsbNumber::Double(3.03)); + let json_value = num.to_json().unwrap(); + assert_eq!(json_value.to_string(), "3.03"); +}