1
use std::{
2
    convert::{TryFrom, TryInto},
3
    fmt::Display,
4
};
5

            
6
use bonsol_schema::ProverVersion as FBSProverVersion;
7

            
8
pub const DIGEST_V1_0_1_BYTES: &str =
9
    "310fe598e8e3e92fa805bc272d7f587898bb8b68c4d5d7938db884abaa76e15c";
10

            
11
pub const DIGEST_V1_2_1_BYTES: &str =
12
    "c101b42bcacd62e35222b1207223250814d05dd41d41f8cadc1f16f86707ae15";
13

            
14
#[derive(Debug, Clone, PartialEq, Eq)]
15
pub enum ProverVersion {
16
    V1_0_1 { verifier_digest: &'static str },
17
    V1_2_1 { verifier_digest: &'static str },
18
    UnsupportedVersion,
19
}
20

            
21
impl Display for ProverVersion {
22
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23
        match self {
24
            ProverVersion::V1_0_1 { .. } => write!(f, "V1_0_1"),
25
            ProverVersion::V1_2_1 { .. } => write!(f, "V1_2_1"),
26
            ProverVersion::UnsupportedVersion => write!(f, "UnsupportedVersion"),
27
        }
28
    }
29
}
30

            
31
#[derive(Debug, Clone, PartialEq, Eq)]
32
pub enum ProverVersionError {
33
    UnsupportedVersion,
34
}
35

            
36
impl Default for ProverVersion {
37
6
    fn default() -> Self {
38
6
        VERSION_V1_2_1
39
6
    }
40
}
41

            
42
impl TryFrom<FBSProverVersion> for ProverVersion {
43
    type Error = ProverVersionError;
44

            
45
3
    fn try_from(prover_version: FBSProverVersion) -> Result<Self, Self::Error> {
46
3
        match prover_version {
47
1
            FBSProverVersion::V1_0_1 => Ok(VERSION_V1_0_1),
48
1
            FBSProverVersion::V1_2_1 | FBSProverVersion::DEFAULT => Ok(VERSION_V1_2_1),
49
1
            _ => Err(ProverVersionError::UnsupportedVersion),
50
        }
51
3
    }
52
}
53

            
54
impl TryInto<FBSProverVersion> for ProverVersion {
55
    type Error = ProverVersionError;
56

            
57
2
    fn try_into(self) -> Result<FBSProverVersion, Self::Error> {
58
2
        // this is to allow for a future error where a version is missed
59
2
        #[allow(unreachable_patterns)]
60
2
        match self {
61
1
            ProverVersion::V1_0_1 { .. } => Ok(FBSProverVersion::V1_0_1),
62
            ProverVersion::V1_2_1 { .. } => Ok(FBSProverVersion::V1_2_1),
63
1
            _ => Err(ProverVersionError::UnsupportedVersion),
64
        }
65
2
    }
66
}
67

            
68
pub const VERSION_V1_0_1: ProverVersion = ProverVersion::V1_0_1 {
69
    verifier_digest: DIGEST_V1_0_1_BYTES,
70
};
71

            
72
pub const VERSION_V1_2_1: ProverVersion = ProverVersion::V1_2_1 {
73
    verifier_digest: DIGEST_V1_2_1_BYTES,
74
};
75

            
76
#[cfg(test)]
77
mod tests {
78
    use super::*;
79

            
80
    #[test]
81
1
    fn test_default_version() {
82
1
        assert_eq!(ProverVersion::default(), VERSION_V1_2_1);
83
1
    }
84

            
85
    #[test]
86
1
    fn test_verify_prover_version() {
87
1
        assert_eq!(
88
1
            VERSION_V1_0_1,
89
1
            ProverVersion::V1_0_1 {
90
1
                verifier_digest: DIGEST_V1_0_1_BYTES
91
1
            }
92
1
        );
93
1
    }
94

            
95
    #[test]
96
1
    fn test_try_from_v1_0_1() {
97
1
        let version = ProverVersion::try_from(FBSProverVersion::V1_0_1);
98
1
        assert!(version.is_ok());
99
1
        assert_eq!(version.unwrap(), VERSION_V1_0_1);
100
1
    }
101

            
102
    #[test]
103
1
    fn test_try_into_v1_0_1() {
104
1
        let fbs_version: Result<FBSProverVersion, ProverVersionError> = VERSION_V1_0_1.try_into();
105
1
        assert!(fbs_version.is_ok());
106
1
        assert_eq!(fbs_version.unwrap(), FBSProverVersion::V1_0_1);
107
1
    }
108

            
109
    #[test]
110
1
    fn test_try_from_unsupported_version() {
111
1
        let unsupported_version = FBSProverVersion(u16::MAX);
112
1
        let version = ProverVersion::try_from(unsupported_version);
113
1
        assert!(version.is_err());
114
1
        assert_eq!(version.unwrap_err(), ProverVersionError::UnsupportedVersion);
115
1
    }
116

            
117
    #[test]
118
1
    fn test_try_into_unsupported_version() {
119
1
        let unsupported_version = ProverVersion::UnsupportedVersion;
120
1
        let fbs_version: Result<FBSProverVersion, ProverVersionError> =
121
1
            unsupported_version.try_into();
122
1
        assert!(fbs_version.is_err());
123
1
        assert_eq!(
124
1
            fbs_version.unwrap_err(),
125
1
            ProverVersionError::UnsupportedVersion
126
1
        );
127
1
    }
128

            
129
    #[test]
130
1
    fn test_default_into_current_version() {
131
1
        let default_version = FBSProverVersion::DEFAULT;
132
1
        let version = ProverVersion::try_from(default_version);
133
1
        assert!(version.is_ok());
134
1
        assert_eq!(version.unwrap(), VERSION_V1_2_1);
135
1
    }
136
}