v0.2.11-pre.002-fix.003

This commit is contained in:
2026-08-25 20:37:09 +02:00
parent 126e8abfcd
commit 2dbddfe367
15 changed files with 499 additions and 271 deletions

View File

@@ -1,25 +1,25 @@
// file: crates/ksp-offchain-transport-lib/src/market_price_decimal.rs
// version: 2
// version: 3
/// Maximum accepted UTF-8 byte length for one textual decimal input.
pub const PRICE_DECIMAL_MAX_INPUT_BYTES: usize = 96;
pub const MARKET_PRICE_DECIMAL_MAX_INPUT_BYTES: usize = 96;
/// Maximum scale retained by the canonical exact decimal representation.
pub const PRICE_DECIMAL_MAX_SCALE: u8 = 18;
pub const MARKET_PRICE_DECIMAL_MAX_SCALE: u8 = 18;
/// Exact positive decimal value used for one successful V1 SOL/USD observation.
///
/// The value is represented as a positive `u128` coefficient plus a bounded decimal scale. Trailing fractional zeroes are removed during construction, and
/// Serde serialization always emits the canonical decimal string instead of an IEEE-754 number.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct PriceDecimal {
pub struct MarketPriceDecimal {
coefficient: u128,
scale: u8,
}
impl PriceDecimal {
impl MarketPriceDecimal {
/// Parses a positive decimal or bounded scientific-notation value without converting through `f64`.
pub fn parse(source: &str) -> ksp_core_lib::Result<Self> {
if source.is_empty() || source.len() > crate::PRICE_DECIMAL_MAX_INPUT_BYTES || source.trim() != source {
if source.is_empty() || source.len() > crate::MARKET_PRICE_DECIMAL_MAX_INPUT_BYTES || source.trim() != source {
return std::result::Result::Err(invalid_decimal_error());
}
let (significand, exponent) = match split_exponent(source) {
@@ -49,7 +49,7 @@ impl PriceDecimal {
};
effective_scale = 0;
}
if effective_scale > i32::from(crate::PRICE_DECIMAL_MAX_SCALE) {
if effective_scale > i32::from(crate::MARKET_PRICE_DECIMAL_MAX_SCALE) {
return std::result::Result::Err(invalid_decimal_error());
}
let mut scale = match u8::try_from(effective_scale) {
@@ -92,21 +92,21 @@ impl PriceDecimal {
}
}
impl std::fmt::Display for PriceDecimal {
impl std::fmt::Display for MarketPriceDecimal {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str(self.to_canonical_string().as_str());
}
}
impl std::str::FromStr for PriceDecimal {
impl std::str::FromStr for MarketPriceDecimal {
type Err = ksp_core_lib::Error;
fn from_str(source: &str) -> std::result::Result<Self, Self::Err> {
return crate::PriceDecimal::parse(source);
return crate::MarketPriceDecimal::parse(source);
}
}
impl serde::Serialize for PriceDecimal {
impl serde::Serialize for MarketPriceDecimal {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
@@ -115,19 +115,19 @@ impl serde::Serialize for PriceDecimal {
}
}
impl<'de> serde::Deserialize<'de> for PriceDecimal {
impl<'de> serde::Deserialize<'de> for MarketPriceDecimal {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
return deserializer.deserialize_str(PriceDecimalVisitor);
return deserializer.deserialize_str(MarketPriceDecimalVisitor);
}
}
struct PriceDecimalVisitor;
struct MarketPriceDecimalVisitor;
impl<'de> serde::de::Visitor<'de> for PriceDecimalVisitor {
type Value = crate::PriceDecimal;
impl<'de> serde::de::Visitor<'de> for MarketPriceDecimalVisitor {
type Value = crate::MarketPriceDecimal;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str("a canonicalizable positive decimal string");
@@ -137,9 +137,9 @@ impl<'de> serde::de::Visitor<'de> for PriceDecimalVisitor {
where
E: serde::de::Error,
{
return match crate::PriceDecimal::parse(value) {
return match crate::MarketPriceDecimal::parse(value) {
std::result::Result::Ok(decimal) => std::result::Result::Ok(decimal),
std::result::Result::Err(_) => std::result::Result::Err(E::custom("invalid KSP price decimal")),
std::result::Result::Err(_) => std::result::Result::Err(E::custom("invalid KSP market-price decimal")),
};
}
}
@@ -157,7 +157,7 @@ fn checked_multiply_power_of_ten(mut value: u128, exponent: u32) -> std::option:
}
fn invalid_decimal_error() -> ksp_core_lib::Error {
return ksp_core_lib::Error::new(crate::ERROR_CODE_PRICE_DECIMAL_INVALID, "invalid exact price decimal");
return ksp_core_lib::Error::new(crate::ERROR_CODE_MARKET_PRICE_DECIMAL_INVALID, "invalid exact market-price decimal");
}
fn significand_digits(significand: &str) -> std::result::Result<(std::string::String, u8), ()> {