levana_perpswap_cosmos/
direction.rs1use std::array::TryFromSliceError;
7use std::convert::From;
8
9use cosmwasm_schema::cw_serde;
10use cosmwasm_std::{StdError, StdResult};
11use cw_storage_plus::{IntKey, Key, KeyDeserialize, Prefixer, PrimaryKey};
12
13use crate::{market_type::MarketType, prelude::*};
14
15#[cw_serde]
17#[derive(Eq, Copy)]
18#[repr(u8)]
19pub enum DirectionToNotional {
20 Long,
22 Short,
24}
25
26#[cw_serde]
28#[derive(Eq, Copy)]
29#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
30pub enum DirectionToBase {
31 Long,
33 Short,
35}
36
37impl DirectionToBase {
38 pub const fn as_str(&self) -> &'static str {
40 match self {
41 Self::Long => "long",
42 Self::Short => "short",
43 }
44 }
45
46 pub fn invert(self) -> Self {
48 match self {
49 Self::Long => Self::Short,
50 Self::Short => Self::Long,
51 }
52 }
53
54 pub fn into_notional(&self, market_type: MarketType) -> DirectionToNotional {
56 match (market_type, self) {
57 (MarketType::CollateralIsQuote, DirectionToBase::Long) => DirectionToNotional::Long,
58 (MarketType::CollateralIsQuote, DirectionToBase::Short) => DirectionToNotional::Short,
59 (MarketType::CollateralIsBase, DirectionToBase::Long) => DirectionToNotional::Short,
60 (MarketType::CollateralIsBase, DirectionToBase::Short) => DirectionToNotional::Long,
61 }
62 }
63}
64
65impl DirectionToNotional {
66 pub const fn as_str(&self) -> &'static str {
68 match self {
69 Self::Long => "long",
70 Self::Short => "short",
71 }
72 }
73
74 pub fn into_base(&self, market_type: MarketType) -> DirectionToBase {
76 match (market_type, self) {
77 (MarketType::CollateralIsQuote, DirectionToNotional::Long) => DirectionToBase::Long,
78 (MarketType::CollateralIsQuote, DirectionToNotional::Short) => DirectionToBase::Short,
79 (MarketType::CollateralIsBase, DirectionToNotional::Long) => DirectionToBase::Short,
80 (MarketType::CollateralIsBase, DirectionToNotional::Short) => DirectionToBase::Long,
81 }
82 }
83
84 pub fn sign(&self) -> Number {
86 match self {
87 DirectionToNotional::Long => Number::ONE,
88 DirectionToNotional::Short => Number::NEG_ONE,
89 }
90 }
91}
92
93impl From<DirectionToNotional> for u8 {
94 fn from(value: DirectionToNotional) -> Self {
95 match value {
96 DirectionToNotional::Long => 0,
97 DirectionToNotional::Short => 1,
98 }
99 }
100}
101
102impl From<&str> for DirectionToNotional {
103 fn from(s: &str) -> Self {
104 match s {
105 "long" => Self::Long,
106 "short" => Self::Short,
107 _ => unimplemented!(),
108 }
109 }
110}
111
112impl<'a> PrimaryKey<'a> for DirectionToNotional {
113 type Prefix = ();
114 type SubPrefix = ();
115 type Suffix = Self;
116 type SuperSuffix = Self;
117
118 fn key(&self) -> Vec<Key> {
119 let val: u8 = u8::from(*self);
120 let key = Key::Val8(val.to_cw_bytes());
121
122 vec![key]
123 }
124}
125
126impl<'a> Prefixer<'a> for DirectionToNotional {
127 fn prefix(&self) -> Vec<Key> {
128 let val: u8 = u8::from(*self);
129 let key = Key::Val8(val.to_cw_bytes());
130 vec![key]
131 }
132}
133
134impl KeyDeserialize for DirectionToNotional {
135 type Output = u8;
136
137 const KEY_ELEMS: u16 = 1;
138
139 #[inline(always)]
140 fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
141 Ok(u8::from_cw_bytes(value.as_slice().try_into().map_err(
142 |err: TryFromSliceError| StdError::generic_err(err.to_string()),
143 )?))
144 }
145}