z_mirror/hare-fmm
git clone https://git.raiguard.me/z_mirror/hare-fmm
88c1a72
trunk
1use fmt; 2use strconv; 3use strings; 4 5// A [[version]] has four components, being major, minor, patch, and build. 6// Build is only used for internal game mechanics, and is not usable by mods. 7type version = [4]u16; 8 9// Any error which may be returned by a version function. 10type version_error = !(strconv::error | version_invalid_len); 11 12// Indicates that the version string has too many or too few parts. Contains 13// the number of parts received. 14type version_invalid_len = !size; 15 16// Indicates the result of comparing two [[version]]s. Also contains some extra 17// variants for dependency validation. 18// 19// The value is encoded in binary as '(eq)(lt)(gt)'. 20type version_cmpres = enum u8 { 21 ANY = 0, 22 EQ, 23 GT, 24 GTEQ, 25 LT, 26 LTEQ = 6, 27}; 28 29// Compares two [[version]]s for equality. 30fn version_cmp(v1: version, v2: version) version_cmpres = { 31 for (let i = 0z; i < len(v1); i += 1) { 32 if (v1[i] > v2[i]) { 33 return version_cmpres::GT; 34 } else if (v1[i] < v2[i]) { 35 return version_cmpres::LT; 36 }; 37 }; 38 return version_cmpres::EQ; 39}; 40 41// Parses a [[version]] from an input string. 42fn version_parse(input: str) (version | version_error) = { 43 let parts = strings::split(strings::trim(input), ".")!; 44 if (len(parts) < 2 || len(parts) > 4) 45 return len(parts): version_invalid_len; 46 let version: version = [0...]; 47 for (let i = 0z; i < len(parts); i += 1) 48 version[i] = strconv::stou16(parts[i])?; 49 return version; 50}; 51 52// Formats a [[version]] for printing. The return value must be freed by the 53// caller. 54fn version_str(ver: version, include_build: bool) str = { 55 if (include_build) { 56 return fmt::asprintf("{}.{}.{}.{}", ver[0], ver[1], ver[2], ver[3])!; 57 } else { 58 return fmt::asprintf("{}.{}.{}", ver[0], ver[1], ver[2])!; 59 }; 60}; 61 62// Converts a [[version_error]] into a user-friendly string. 63fn version_strerror(err: version_error) str = { 64 match (err) { 65 case version_invalid_len => 66 return "Invalid number of version parts"; 67 case let err: strconv::error => 68 return strconv::strerror(err); 69 }; 70};