daml_lf/
version.rs

1use crate::DamlLfError;
2use bounded_static::ToStatic;
3use serde::Serialize;
4use std::convert::TryFrom;
5use std::fmt::{Display, Error, Formatter};
6
7/// Daml Ledger Fragment language version.
8#[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
49/// Minimum Daml LF language version support for a feature.
50pub 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/// Daml Ledger Fragment language V1 minor version.
147#[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}