penumbra_sdk_dex/lp/
view.rs

1use penumbra_sdk_proto::{penumbra::core::component::dex::v1 as pb, DomainType};
2use serde::{Deserialize, Serialize};
3
4use crate::PositionOpen;
5
6use super::PositionMetadata;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9#[serde(try_from = "pb::PositionOpenView", into = "pb::PositionOpenView")]
10pub enum PositionOpenView {
11    Visible {
12        action: PositionOpen,
13        metadata: PositionMetadata,
14    },
15    Opaque {
16        action: PositionOpen,
17    },
18}
19
20impl DomainType for PositionOpenView {
21    type Proto = pb::PositionOpenView;
22}
23
24impl From<PositionOpenView> for pb::PositionOpenView {
25    fn from(view: PositionOpenView) -> Self {
26        match view {
27            PositionOpenView::Visible { action, metadata } => Self {
28                position_open_view: Some(pb::position_open_view::PositionOpenView::Visible(
29                    pb::position_open_view::Visible {
30                        action: Some(action.into()),
31                        metadata: Some(metadata.into()),
32                    },
33                )),
34            },
35            PositionOpenView::Opaque { action } => Self {
36                position_open_view: Some(pb::position_open_view::PositionOpenView::Opaque(
37                    pb::position_open_view::Opaque {
38                        action: Some(action.into()),
39                    },
40                )),
41            },
42        }
43    }
44}
45
46impl TryFrom<pb::PositionOpenView> for PositionOpenView {
47    type Error = anyhow::Error;
48
49    fn try_from(proto: pb::PositionOpenView) -> Result<Self, Self::Error> {
50        use anyhow::Context;
51
52        match proto.position_open_view {
53            Some(pb::position_open_view::PositionOpenView::Visible(visible)) => {
54                let action = visible
55                    .action
56                    .ok_or_else(|| anyhow::anyhow!("missing action in Visible PositionOpenView"))?
57                    .try_into()?;
58                let metadata = visible
59                    .metadata
60                    .ok_or_else(|| anyhow::anyhow!("missing metadata in Visible PositionOpenView"))?
61                    .try_into()?;
62
63                Ok(PositionOpenView::Visible { action, metadata })
64            }
65            Some(pb::position_open_view::PositionOpenView::Opaque(opaque)) => {
66                let action = opaque
67                    .action
68                    .ok_or_else(|| anyhow::anyhow!("missing action in Opaque PositionOpenView"))?
69                    .try_into()
70                    .context("invalid action in Opaque PositionOpenView")?;
71
72                Ok(PositionOpenView::Opaque { action })
73            }
74            None => Err(anyhow::anyhow!("missing position_open_view")),
75        }
76    }
77}
78
79impl From<PositionOpenView> for PositionOpen {
80    fn from(value: PositionOpenView) -> Self {
81        match value {
82            PositionOpenView::Visible { action, .. } => action,
83            PositionOpenView::Opaque { action } => action,
84        }
85    }
86}