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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::version::GroveVersion;

pub mod error;
pub mod version;

#[macro_export]
macro_rules! check_grovedb_v0_with_cost {
    ($method:expr, $version:expr) => {{
        const EXPECTED_VERSION: u16 = 0;
        if $version != EXPECTED_VERSION {
            return Err(GroveVersionError::UnknownVersionMismatch {
                method: $method.to_string(),
                known_versions: vec![EXPECTED_VERSION],
                received: $version,
            }
            .into())
            .wrap_with_cost(OperationCost::default());
        }
    }};
}

#[macro_export]
macro_rules! check_grovedb_v0 {
    ($method:expr, $version:expr) => {{
        const EXPECTED_VERSION: u16 = 0;
        if $version != EXPECTED_VERSION {
            return Err(GroveVersionError::UnknownVersionMismatch {
                method: $method.to_string(),
                known_versions: vec![EXPECTED_VERSION],
                received: $version,
            }
            .into());
        }
    }};
}

#[macro_export]
macro_rules! check_merk_v0_with_cost {
    ($method:expr, $version:expr) => {{
        const EXPECTED_VERSION: u16 = 0;
        if $version != EXPECTED_VERSION {
            return Err(GroveVersionError::UnknownVersionMismatch {
                method: $method.to_string(),
                known_versions: vec![EXPECTED_VERSION],
                received: $version,
            }
            .into())
            .wrap_with_cost(OperationCost::default());
        }
    }};
}

#[macro_export]
macro_rules! check_merk_v0 {
    ($method:expr, $version:expr) => {{
        const EXPECTED_VERSION: u16 = 0;
        if $version != EXPECTED_VERSION {
            return Err(GroveVersionError::UnknownVersionMismatch {
                method: $method.to_string(),
                known_versions: vec![EXPECTED_VERSION],
                received: $version,
            }
            .into());
        }
    }};
}

pub trait TryFromVersioned<T>: Sized {
    /// The type returned in the event of a conversion error.
    type Error;

    /// Performs the conversion.
    fn try_from_versioned(value: T, grove_version: &GroveVersion) -> Result<Self, Self::Error>;
}

pub trait TryIntoVersioned<T>: Sized {
    /// The type returned in the event of a conversion error.
    type Error;

    /// Performs the conversion.
    fn try_into_versioned(self, grove_version: &GroveVersion) -> Result<T, Self::Error>;
}

impl<T, U> TryIntoVersioned<U> for T
where
    U: TryFromVersioned<T>,
{
    type Error = U::Error;

    #[inline]
    fn try_into_versioned(self, grove_version: &GroveVersion) -> Result<U, U::Error> {
        U::try_from_versioned(self, grove_version)
    }
}

impl<T, U> TryFromVersioned<U> for T
where
    T: TryFrom<U>,
{
    type Error = T::Error;

    #[inline]
    fn try_from_versioned(value: U, _grove_version: &GroveVersion) -> Result<Self, Self::Error> {
        T::try_from(value)
    }
}