v2 / vlib / semver / parse.v
82 lines · 73 sloc · 2.02 KB · bd803a92082a85d72734aef2f5aaf18e960e219d
Raw
1module semver
2
3// * Private structs and functions.
4struct RawVersion {
5 prerelease string
6 metadata string
7mut:
8 raw_ints []string
9}
10
11const ver_major = 0
12const ver_minor = 1
13const ver_patch = 2
14const versions = [ver_major, ver_minor, ver_patch]
15
16// TODO: Rewrite using regexps?
17// /(\d+)\.(\d+)\.(\d+)(?:\-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-]+))?/
18fn parse(input string) RawVersion {
19 mut raw_version := input
20 mut prerelease := ''
21 mut metadata := ''
22 plus_idx := raw_version.last_index_u8(`+`)
23 if plus_idx > 0 {
24 metadata = raw_version[(plus_idx + 1)..]
25 raw_version = raw_version[0..plus_idx]
26 }
27 hyphen_idx := raw_version.index_('-')
28 if hyphen_idx > 0 {
29 prerelease = raw_version[(hyphen_idx + 1)..]
30 raw_version = raw_version[0..hyphen_idx]
31 }
32 raw_ints := raw_version.split('.')
33 return RawVersion{
34 prerelease: prerelease
35 metadata: metadata
36 raw_ints: raw_ints
37 }
38}
39
40fn (ver RawVersion) is_valid() bool {
41 if ver.raw_ints.len != 3 {
42 return false
43 }
44 return is_valid_number(ver.raw_ints[ver_major]) && is_valid_number(ver.raw_ints[ver_minor])
45 && is_valid_number(ver.raw_ints[ver_patch]) && is_valid_string(ver.prerelease)
46 && is_valid_string(ver.metadata)
47}
48
49fn (ver RawVersion) is_missing(typ int) bool {
50 return typ >= ver.raw_ints.len - 1
51}
52
53fn (raw_ver RawVersion) coerce() !Version {
54 ver := raw_ver.complete()
55 if !is_valid_number(ver.raw_ints[ver_major]) {
56 return error('Invalid major version: ${ver.raw_ints}[ver_major]')
57 }
58 return ver.to_version()
59}
60
61fn (raw_ver RawVersion) complete() RawVersion {
62 mut raw_ints := raw_ver.raw_ints.clone()
63 for raw_ints.len < 3 {
64 raw_ints << '0'
65 }
66 return RawVersion{
67 prerelease: raw_ver.prerelease
68 metadata: raw_ver.metadata
69 raw_ints: raw_ints
70 }
71}
72
73fn (raw_ver RawVersion) validate() ?Version {
74 if !raw_ver.is_valid() {
75 return none
76 }
77 return raw_ver.to_version()
78}
79
80fn (raw_ver RawVersion) to_version() Version {
81 return Version{raw_ver.raw_ints[ver_major].int(), raw_ver.raw_ints[ver_minor].int(), raw_ver.raw_ints[ver_patch].int(), raw_ver.prerelease, raw_ver.metadata}
82}
83