levana_perpswap_cosmos/contracts/market/position/
collateral_and_usd.rs

1//! Defines data types combining collateral and USD.
2//!
3//! The purpose of this is to avoid accidentally updating one field in a data
4//! structure without updating the other.
5
6use crate::prelude::*;
7
8/// Collateral and USD which will always be non-negative.
9#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq, Copy, Default)]
10pub struct CollateralAndUsd {
11    collateral: Collateral,
12    usd: Usd,
13}
14
15impl CollateralAndUsd {
16    /// Create a new value from the given collateral
17    pub fn new(collateral: Collateral, price_point: &PricePoint) -> Self {
18        CollateralAndUsd {
19            collateral,
20            usd: price_point.collateral_to_usd(collateral),
21        }
22    }
23
24    /// Creates a new value from the raw collateral and USD values.
25    pub fn from_pair(collateral: Collateral, usd: Usd) -> Self {
26        CollateralAndUsd { collateral, usd }
27    }
28
29    /// Get the collateral component
30    pub fn collateral(&self) -> Collateral {
31        self.collateral
32    }
33
34    /// Get the USD component
35    pub fn usd(&self) -> Usd {
36        self.usd
37    }
38
39    /// Add a new value
40    pub fn checked_add_assign(
41        &mut self,
42        collateral: Collateral,
43        price_point: &PricePoint,
44    ) -> Result<()> {
45        self.collateral = self.collateral.checked_add(collateral)?;
46        self.usd = self
47            .usd
48            .checked_add(price_point.collateral_to_usd(collateral))?;
49        Ok(())
50    }
51}
52
53/// Collateral and USD which can become negative
54#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq, Copy, Default)]
55pub struct SignedCollateralAndUsd {
56    collateral: Signed<Collateral>,
57    usd: Signed<Usd>,
58}
59
60impl SignedCollateralAndUsd {
61    /// Create a new value from the given collateral
62    pub fn new(collateral: Signed<Collateral>, price_point: &PricePoint) -> Self {
63        SignedCollateralAndUsd {
64            collateral,
65            usd: collateral.map(|x| price_point.collateral_to_usd(x)),
66        }
67    }
68
69    /// Get the collateral component
70    pub fn collateral(&self) -> Signed<Collateral> {
71        self.collateral
72    }
73
74    /// Get the USD component
75    pub fn usd(&self) -> Signed<Usd> {
76        self.usd
77    }
78
79    /// Add a new value
80    pub fn checked_add_assign(
81        &mut self,
82        collateral: Signed<Collateral>,
83        price_point: &PricePoint,
84    ) -> Result<()> {
85        self.collateral = self.collateral.checked_add(collateral)?;
86        self.usd = self
87            .usd
88            .checked_add(collateral.map(|x| price_point.collateral_to_usd(x)))?;
89        Ok(())
90    }
91}