|
8 | 8 | serde::{de::Error, Deserialize, Serialize},
|
9 | 9 | std::{
|
10 | 10 | num::NonZeroI64,
|
11 |
| - ops::{Add, Deref, DerefMut, Div, Mul, Sub}, |
| 11 | + ops::{Add, Deref, DerefMut, Div, Sub}, |
12 | 12 | time::{SystemTime, UNIX_EPOCH},
|
13 | 13 | },
|
14 | 14 | };
|
@@ -46,9 +46,6 @@ impl TimestampUs {
|
46 | 46 | pub struct Price(pub NonZeroI64);
|
47 | 47 |
|
48 | 48 | impl Price {
|
49 |
| - // TODO: define exponent in price feed metadata instead |
50 |
| - pub const TMP_EXPONENT: u32 = 8; |
51 |
| - |
52 | 49 | pub fn from_integer(value: i64, exponent: u32) -> anyhow::Result<Price> {
|
53 | 50 | let coef = 10i64.checked_pow(exponent).context("overflow")?;
|
54 | 51 | let value = value.checked_mul(coef).context("overflow")?;
|
@@ -77,13 +74,20 @@ impl Price {
|
77 | 74 | pub fn into_inner(self) -> NonZeroI64 {
|
78 | 75 | self.0
|
79 | 76 | }
|
80 |
| -} |
81 | 77 |
|
82 |
| -impl TryInto<f64> for Price { |
83 |
| - type Error = anyhow::Error; |
| 78 | + pub fn to_f64(self, exponent: u32) -> anyhow::Result<f64> { |
| 79 | + Ok(self.0.get() as f64 / 10i64.checked_pow(exponent).context("overflow")? as f64) |
| 80 | + } |
| 81 | + |
| 82 | + pub fn mul(self, rhs: Price, rhs_exponent: u32) -> anyhow::Result<Price> { |
| 83 | + let left_value = i128::from(self.0.get()); |
| 84 | + let right_value = i128::from(rhs.0.get()); |
84 | 85 |
|
85 |
| - fn try_into(self) -> Result<f64, Self::Error> { |
86 |
| - Ok(self.0.get() as f64 / 10i64.checked_pow(Self::TMP_EXPONENT).context("overflow")? as f64) |
| 86 | + let value = left_value * right_value / 10i128.pow(rhs_exponent); |
| 87 | + let value = value.try_into()?; |
| 88 | + NonZeroI64::new(value) |
| 89 | + .context("zero price is unsupported") |
| 90 | + .map(Self) |
87 | 91 | }
|
88 | 92 | }
|
89 | 93 |
|
@@ -121,21 +125,6 @@ impl Div<i64> for Price {
|
121 | 125 | }
|
122 | 126 | }
|
123 | 127 |
|
124 |
| -impl Mul<Price> for Price { |
125 |
| - type Output = Option<Price>; |
126 |
| - fn mul(self, rhs: Price) -> Self::Output { |
127 |
| - let left_value = i128::from(self.0.get()); |
128 |
| - let right_value = i128::from(rhs.0.get()); |
129 |
| - |
130 |
| - let value = left_value * right_value / 10i128.pow(Price::TMP_EXPONENT); |
131 |
| - let value = match value.try_into() { |
132 |
| - Ok(value) => value, |
133 |
| - Err(_) => return None, |
134 |
| - }; |
135 |
| - NonZeroI64::new(value).map(Self) |
136 |
| - } |
137 |
| -} |
138 |
| - |
139 | 128 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
140 | 129 | #[serde(rename_all = "camelCase")]
|
141 | 130 | pub enum PriceFeedProperty {
|
|
0 commit comments