penumbra_asset/
equivalent_value.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use crate::asset::Metadata;
use penumbra_num::Amount;
use penumbra_proto::{penumbra::core::asset::v1 as pb, DomainType};
use serde::{Deserialize, Serialize};

/// An equivalent value in terms of a different numeraire.
///
/// This is used within
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
#[serde(try_from = "pb::EquivalentValue", into = "pb::EquivalentValue")]
pub struct EquivalentValue {
    /// The equivalent amount of the parent [`Value`] in terms of the numeraire.
    pub equivalent_amount: Amount,
    /// Metadata describing the numeraire.
    pub numeraire: Metadata,
    /// If nonzero, gives some idea of when the equivalent value was estimated (in terms of block height).
    pub as_of_height: u64,
}

impl DomainType for EquivalentValue {
    type Proto = pb::EquivalentValue;
}

impl From<EquivalentValue> for pb::EquivalentValue {
    fn from(v: EquivalentValue) -> Self {
        pb::EquivalentValue {
            equivalent_amount: Some(v.equivalent_amount.into()),
            numeraire: Some(v.numeraire.into()),
            as_of_height: v.as_of_height,
        }
    }
}

impl TryFrom<pb::EquivalentValue> for EquivalentValue {
    type Error = anyhow::Error;
    fn try_from(value: pb::EquivalentValue) -> Result<Self, Self::Error> {
        Ok(EquivalentValue {
            equivalent_amount: value
                .equivalent_amount
                .ok_or_else(|| anyhow::anyhow!("missing equivalent_amount field"))?
                .try_into()?,
            numeraire: value
                .numeraire
                .ok_or_else(|| anyhow::anyhow!("missing numeraire field"))?
                .try_into()?,
            as_of_height: value.as_of_height,
        })
    }
}