| ... | @@ -488,11 +488,26 @@ pub const Version = struct { | ... | @@ -488,11 +488,26 @@ pub const Version = struct { |
| 488 | } | 488 | } |
| 489 | | 489 | |
| 490 | pub fn parse(text: []const u8) !Version { | 490 | pub fn parse(text: []const u8) !Version { |
| 491 | var it = std.mem.split(text, "."); | 491 | var end: usize = 0; |
| | 492 | while (end < text.len) : (end += 1) { |
| | 493 | const c = text[end]; |
| | 494 | if (!std.ascii.isDigit(c) and c != '.') break; |
| | 495 | } |
| | 496 | // found no digits or '.' before unexpected character |
| | 497 | if (end == 0) return error.InvalidVersion; |
| | 498 | |
| | 499 | var it = std.mem.split(text[0..end], "."); |
| | 500 | // substring is not empty, first call will succeed |
| | 501 | const major = it.next().?; |
| | 502 | if (major.len == 0) return error.InvalidVersion; |
| | 503 | const minor = it.next() orelse "0"; |
| | 504 | // ignore 'patch' if 'minor' is invalid |
| | 505 | const patch = if (minor.len == 0) "0" else (it.next() orelse "0"); |
| | 506 | |
| 492 | return Version{ | 507 | return Version{ |
| 493 | .major = try std.fmt.parseInt(u32, it.next() orelse return error.InvalidVersion, 10), | 508 | .major = try std.fmt.parseUnsigned(u32, major, 10), |
| 494 | .minor = try std.fmt.parseInt(u32, it.next() orelse "0", 10), | 509 | .minor = try std.fmt.parseUnsigned(u32, if (minor.len == 0) "0" else minor, 10), |
| 495 | .patch = try std.fmt.parseInt(u32, it.next() orelse "0", 10), | 510 | .patch = try std.fmt.parseUnsigned(u32, if (patch.len == 0) "0" else patch, 10), |
| 496 | }; | 511 | }; |
| 497 | } | 512 | } |
| 498 | | 513 | |