1use crate::DamlLfError;
2use bounded_static::ToStatic;
3use serde::Serialize;
4use std::convert::TryFrom;
5use std::fmt::{Display, Error, Formatter};
6
7#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, ToStatic)]
9pub enum LanguageVersion {
10 Lv0,
11 Lv1(LanguageV1MinorVersion),
12}
13
14impl LanguageVersion {
15 pub const V0: LanguageVersion = LanguageVersion::Lv0;
16 pub const V1_0: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V0);
17 pub const V1_1: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V1);
18 pub const V1_11: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V11);
19 pub const V1_12: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V12);
20 pub const V1_13: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V13);
21 pub const V1_14: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V14);
22 pub const V1_2: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V2);
23 pub const V1_3: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V3);
24 pub const V1_4: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V4);
25 pub const V1_5: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V5);
26 pub const V1_6: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V6);
27 pub const V1_7: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V7);
28 pub const V1_8: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::V8);
29 pub const V1_DEV: LanguageVersion = LanguageVersion::Lv1(LanguageV1MinorVersion::Dev);
30
31 pub fn new_v1(minor: LanguageV1MinorVersion) -> Self {
32 LanguageVersion::Lv1(minor)
33 }
34
35 pub fn supports_feature(self, feature_version: &LanguageFeatureVersion) -> bool {
36 self >= feature_version.min_version
37 }
38}
39
40impl Display for LanguageVersion {
41 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
42 match *self {
43 LanguageVersion::Lv0 => write!(f, "v0"),
44 LanguageVersion::Lv1(minor) => write!(f, "v1.{}", minor),
45 }
46 }
47}
48
49pub struct LanguageFeatureVersion {
51 pub name: &'static str,
52 pub min_version: LanguageVersion,
53}
54
55impl LanguageFeatureVersion {
56 pub const ANY_TYPE: LanguageFeatureVersion = LanguageFeatureVersion {
57 name: "ANY_TYPE",
58 min_version: LanguageVersion::V1_7,
59 };
60 pub const ARROW_TYPE: LanguageFeatureVersion = LanguageFeatureVersion {
61 name: "ARROW_TYPE",
62 min_version: LanguageVersion::V1_1,
63 };
64 pub const CHOICE_OBSERVERS: LanguageFeatureVersion = LanguageFeatureVersion {
65 name: "CHOICE_OBSERVERS",
66 min_version: LanguageVersion::V1_11,
67 };
68 pub const COERCE_CONTRACT_ID: LanguageFeatureVersion = LanguageFeatureVersion {
69 name: "COERCE_CONTRACT_ID",
70 min_version: LanguageVersion::V1_5,
71 };
72 pub const COMPLEX_CONTACT_KEYS: LanguageFeatureVersion = LanguageFeatureVersion {
73 name: "COMPLEX_CONTACT_KEYS",
74 min_version: LanguageVersion::V1_4,
75 };
76 pub const CONTRACT_KEYS: LanguageFeatureVersion = LanguageFeatureVersion {
77 name: "CONTRACT_KEYS",
78 min_version: LanguageVersion::V1_3,
79 };
80 pub const DEFAULT: LanguageFeatureVersion = LanguageFeatureVersion {
81 name: "DEFAULT",
82 min_version: LanguageVersion::V1_0,
83 };
84 pub const ENUM: LanguageFeatureVersion = LanguageFeatureVersion {
85 name: "ENUM",
86 min_version: LanguageVersion::V1_6,
87 };
88 pub const INTERNED_DOTTED_NAMES: LanguageFeatureVersion = LanguageFeatureVersion {
89 name: "INTERNED_DOTTED_NAMES",
90 min_version: LanguageVersion::V1_7,
91 };
92 pub const INTERNED_PACKAGE_ID: LanguageFeatureVersion = LanguageFeatureVersion {
93 name: "INTERNED_PACKAGE_ID",
94 min_version: LanguageVersion::V1_6,
95 };
96 pub const INTERNED_STRINGS: LanguageFeatureVersion = LanguageFeatureVersion {
97 name: "INTERNED_STRINGS",
98 min_version: LanguageVersion::V1_7,
99 };
100 pub const NUMBER_PARSING: LanguageFeatureVersion = LanguageFeatureVersion {
101 name: "NUMBER_PARSING",
102 min_version: LanguageVersion::V1_5,
103 };
104 pub const NUMERIC: LanguageFeatureVersion = LanguageFeatureVersion {
105 name: "NUMERIC",
106 min_version: LanguageVersion::V1_7,
107 };
108 pub const OPTIONAL: LanguageFeatureVersion = LanguageFeatureVersion {
109 name: "OPTIONAL",
110 min_version: LanguageVersion::V1_1,
111 };
112 pub const OPTIONAL_EXERCISE_ACTOR: LanguageFeatureVersion = LanguageFeatureVersion {
113 name: "OPTIONAL_EXERCISE_ACTOR",
114 min_version: LanguageVersion::V1_5,
115 };
116 pub const PACKAGE_METADATA: LanguageFeatureVersion = LanguageFeatureVersion {
117 name: "PACKAGE_METADATA",
118 min_version: LanguageVersion::V1_8,
119 };
120 pub const PARTY_ORDERING: LanguageFeatureVersion = LanguageFeatureVersion {
121 name: "PARTY_ORDERING",
122 min_version: LanguageVersion::V1_1,
123 };
124 pub const PARTY_TEXT_CONVERSIONS: LanguageFeatureVersion = LanguageFeatureVersion {
125 name: "PARTY_TEXT_CONVERSIONS",
126 min_version: LanguageVersion::V1_2,
127 };
128 pub const SHA_TEXT: LanguageFeatureVersion = LanguageFeatureVersion {
129 name: "SHA_TEXT",
130 min_version: LanguageVersion::V1_2,
131 };
132 pub const TEXTMAP: LanguageFeatureVersion = LanguageFeatureVersion {
133 name: "TEXTMAP",
134 min_version: LanguageVersion::V1_3,
135 };
136 pub const TEXT_PACKING: LanguageFeatureVersion = LanguageFeatureVersion {
137 name: "TEXT_PACKING",
138 min_version: LanguageVersion::V1_6,
139 };
140 pub const TYPE_REP: LanguageFeatureVersion = LanguageFeatureVersion {
141 name: "TYPE_REP",
142 min_version: LanguageVersion::V1_7,
143 };
144}
145
146#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, ToStatic)]
148pub enum LanguageV1MinorVersion {
149 V0,
150 V1,
151 V2,
152 V3,
153 V4,
154 V5,
155 V6,
156 V7,
157 V8,
158 V11,
159 V12,
160 V13,
161 V14,
162 Dev,
163}
164
165impl Display for LanguageV1MinorVersion {
166 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
167 match *self {
168 LanguageV1MinorVersion::V0 => write!(f, "0"),
169 LanguageV1MinorVersion::V1 => write!(f, "1"),
170 LanguageV1MinorVersion::V2 => write!(f, "2"),
171 LanguageV1MinorVersion::V3 => write!(f, "3"),
172 LanguageV1MinorVersion::V4 => write!(f, "4"),
173 LanguageV1MinorVersion::V5 => write!(f, "5"),
174 LanguageV1MinorVersion::V6 => write!(f, "6"),
175 LanguageV1MinorVersion::V7 => write!(f, "7"),
176 LanguageV1MinorVersion::V8 => write!(f, "8"),
177 LanguageV1MinorVersion::V11 => write!(f, "11"),
178 LanguageV1MinorVersion::V12 => write!(f, "12"),
179 LanguageV1MinorVersion::V13 => write!(f, "13"),
180 LanguageV1MinorVersion::V14 => write!(f, "14"),
181 LanguageV1MinorVersion::Dev => write!(f, "dev"),
182 }
183 }
184}
185
186impl TryFrom<&str> for LanguageV1MinorVersion {
187 type Error = DamlLfError;
188
189 fn try_from(minor_version: &str) -> Result<Self, Self::Error> {
190 match minor_version {
191 "0" => Ok(LanguageV1MinorVersion::V0),
192 "1" => Ok(LanguageV1MinorVersion::V1),
193 "2" => Ok(LanguageV1MinorVersion::V2),
194 "3" => Ok(LanguageV1MinorVersion::V3),
195 "4" => Ok(LanguageV1MinorVersion::V4),
196 "5" => Ok(LanguageV1MinorVersion::V5),
197 "6" => Ok(LanguageV1MinorVersion::V6),
198 "7" => Ok(LanguageV1MinorVersion::V7),
199 "8" => Ok(LanguageV1MinorVersion::V8),
200 "11" => Ok(LanguageV1MinorVersion::V11),
201 "12" => Ok(LanguageV1MinorVersion::V12),
202 "13" => Ok(LanguageV1MinorVersion::V13),
203 "14" => Ok(LanguageV1MinorVersion::V14),
204 "dev" => Ok(LanguageV1MinorVersion::Dev),
205 _ => Err(DamlLfError::new_unknown_version(minor_version)),
206 }
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::{LanguageV1MinorVersion, LanguageVersion};
213
214 #[test]
215 fn test_minor_version_ordering() {
216 assert!(LanguageV1MinorVersion::V0 < LanguageV1MinorVersion::V1);
217 assert!(LanguageV1MinorVersion::V1 < LanguageV1MinorVersion::V2);
218 assert!(LanguageV1MinorVersion::V2 < LanguageV1MinorVersion::V3);
219 assert!(LanguageV1MinorVersion::V3 < LanguageV1MinorVersion::V4);
220 assert!(LanguageV1MinorVersion::V4 < LanguageV1MinorVersion::V5);
221 assert!(LanguageV1MinorVersion::V5 < LanguageV1MinorVersion::V6);
222 assert!(LanguageV1MinorVersion::V6 < LanguageV1MinorVersion::V7);
223 assert!(LanguageV1MinorVersion::V7 < LanguageV1MinorVersion::V8);
224 assert!(LanguageV1MinorVersion::V8 < LanguageV1MinorVersion::V11);
225 assert!(LanguageV1MinorVersion::V11 < LanguageV1MinorVersion::V12);
226 assert!(LanguageV1MinorVersion::V12 < LanguageV1MinorVersion::V13);
227 assert!(LanguageV1MinorVersion::V13 < LanguageV1MinorVersion::V14);
228 assert!(LanguageV1MinorVersion::V14 < LanguageV1MinorVersion::Dev);
229 }
230
231 #[test]
232 fn test_version_matches() {
233 assert_eq!(LanguageVersion::V1_7, LanguageVersion::Lv1(LanguageV1MinorVersion::V7));
234 assert_ne!(LanguageVersion::V1_7, LanguageVersion::V1_6);
235 }
236
237 #[test]
238 fn test_version_ordering() {
239 assert!(LanguageVersion::V0 < LanguageVersion::V1_0);
240 assert!(LanguageVersion::V1_0 < LanguageVersion::V1_1);
241 assert!(LanguageVersion::V1_1 < LanguageVersion::V1_2);
242 assert!(LanguageVersion::V1_2 < LanguageVersion::V1_3);
243 assert!(LanguageVersion::V1_3 < LanguageVersion::V1_4);
244 assert!(LanguageVersion::V1_4 < LanguageVersion::V1_5);
245 assert!(LanguageVersion::V1_5 < LanguageVersion::V1_6);
246 assert!(LanguageVersion::V1_6 < LanguageVersion::V1_7);
247 assert!(LanguageVersion::V1_7 < LanguageVersion::V1_8);
248 assert!(LanguageVersion::V1_8 < LanguageVersion::V1_11);
249 assert!(LanguageVersion::V1_11 < LanguageVersion::V1_12);
250 assert!(LanguageVersion::V1_12 < LanguageVersion::V1_13);
251 assert!(LanguageVersion::V1_13 < LanguageVersion::V1_14);
252 assert!(LanguageVersion::V1_14 < LanguageVersion::V1_DEV);
253 }
254
255 #[test]
256 fn test_display_version() {
257 assert_eq!("v0", LanguageVersion::V0.to_string());
258 assert_eq!("v1.7", LanguageVersion::V1_7.to_string());
259 assert_eq!("v1.dev", LanguageVersion::V1_DEV.to_string());
260 }
261}