templar_common/
registry.rs1use near_sdk::{
2 json_types::{Base58CryptoHash, U64},
3 near,
4};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[cfg_attr(feature = "rpc", derive(clap::ValueEnum))]
8#[near(serializers = [json, borsh])]
9pub enum DeployMode {
10 Normal,
11 GlobalHash,
12}
13
14impl std::fmt::Display for DeployMode {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 match self {
17 DeployMode::Normal => write!(f, "Normal"),
18 DeployMode::GlobalHash => write!(f, "GlobalHash"),
19 }
20 }
21}
22
23#[derive(Clone, Debug, PartialEq, Eq)]
24#[near(serializers = [borsh, json])]
25pub struct Deployment {
26 pub version_key: String,
27 pub code_hash: Base58CryptoHash,
28 pub block_height: U64,
29}
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
36#[near(serializers = [json])]
37pub enum VersionAvailability {
38 Stored { code_len: u32 },
40 Global,
42 Removed,
44}
45
46impl VersionAvailability {
47 pub fn is_deployable(self) -> bool {
48 matches!(self, Self::Stored { .. } | Self::Global)
49 }
50}
51
52#[derive(Clone, Copy, Debug, PartialEq, Eq)]
54#[near(serializers = [json])]
55pub struct VersionInfo {
56 pub code_hash: Base58CryptoHash,
59 pub availability: VersionAvailability,
60}
61
62#[derive(Clone, Debug, PartialEq, Eq)]
67#[near(serializers = [json])]
68pub enum RegistryEntryView {
69 Reserved,
71 Deployed(Deployment),
72}
73
74impl RegistryEntryView {
75 pub fn deployment(&self) -> Option<&Deployment> {
76 match self {
77 Self::Reserved => None,
78 Self::Deployed(deployment) => Some(deployment),
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use near_sdk::serde_json::{self, json};
86 use rstest::rstest;
87
88 use super::*;
89
90 fn deployment() -> Deployment {
91 Deployment {
92 version_key: "market@1.5.0".to_string(),
93 code_hash: Base58CryptoHash::from([7u8; 32]),
94 block_height: 42.into(),
95 }
96 }
97
98 #[rstest]
99 #[case(VersionAvailability::Stored { code_len: 521_039 }, json!({ "Stored": { "code_len": 521_039 } }))]
100 #[case(VersionAvailability::Global, json!("Global"))]
101 #[case(VersionAvailability::Removed, json!("Removed"))]
102 fn availability_wire_format(
103 #[case] availability: VersionAvailability,
104 #[case] expected: serde_json::Value,
105 ) {
106 assert_eq!(serde_json::to_value(availability).unwrap(), expected);
107 assert_eq!(
108 serde_json::from_value::<VersionAvailability>(expected).unwrap(),
109 availability,
110 );
111 }
112
113 #[rstest]
116 #[case(VersionAvailability::Stored { code_len: 1 }, true)]
117 #[case(VersionAvailability::Global, true)]
118 #[case(VersionAvailability::Removed, false)]
119 fn deployability(#[case] availability: VersionAvailability, #[case] expected: bool) {
120 assert_eq!(availability.is_deployable(), expected);
121 }
122
123 #[test]
124 fn version_info_round_trips() {
125 let info = VersionInfo {
126 code_hash: Base58CryptoHash::from([3u8; 32]),
127 availability: VersionAvailability::Stored { code_len: 128 },
128 };
129 let value = serde_json::to_value(info).unwrap();
130 assert_eq!(serde_json::from_value::<VersionInfo>(value).unwrap(), info);
131 }
132
133 #[test]
134 fn reserved_is_distinguishable_from_deployed() {
135 let reserved = RegistryEntryView::Reserved;
136 assert_eq!(serde_json::to_value(&reserved).unwrap(), json!("Reserved"));
137 assert_eq!(reserved.deployment(), None);
138
139 let deployed = RegistryEntryView::Deployed(deployment());
140 assert_eq!(deployed.deployment(), Some(&deployment()));
141 assert_eq!(
142 serde_json::from_value::<RegistryEntryView>(serde_json::to_value(&deployed).unwrap())
143 .unwrap(),
144 deployed,
145 );
146 }
147}