aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/semver/parse.v
blob: 3443f59993d0cc6d7232ac6e506333b0b2a7c8f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
module semver

// * Private structs and functions.
struct RawVersion {
	prerelease string
	metadata   string
mut:
	raw_ints []string
}

const (
	ver_major = 0
	ver_minor = 1
	ver_patch = 2
	versions  = [ver_major, ver_minor, ver_patch]
)

// TODO: Rewrite using regexps?
// /(\d+)\.(\d+)\.(\d+)(?:\-([0-9A-Za-z-.]+))?(?:\+([0-9A-Za-z-]+))?/
fn parse(input string) RawVersion {
	mut raw_version := input
	mut prerelease := ''
	mut metadata := ''
	plus_idx := raw_version.last_index('+') or { -1 }
	if plus_idx > 0 {
		metadata = raw_version[(plus_idx + 1)..]
		raw_version = raw_version[0..plus_idx]
	}
	hyphen_idx := raw_version.index('-') or { -1 }
	if hyphen_idx > 0 {
		prerelease = raw_version[(hyphen_idx + 1)..]
		raw_version = raw_version[0..hyphen_idx]
	}
	raw_ints := raw_version.split('.')
	return RawVersion{
		prerelease: prerelease
		metadata: metadata
		raw_ints: raw_ints
	}
}

fn (ver RawVersion) is_valid() bool {
	if ver.raw_ints.len != 3 {
		return false
	}
	return is_valid_number(ver.raw_ints[semver.ver_major])
		&& is_valid_number(ver.raw_ints[semver.ver_minor])
		&& is_valid_number(ver.raw_ints[semver.ver_patch]) && is_valid_string(ver.prerelease)
		&& is_valid_string(ver.metadata)
}

fn (ver RawVersion) is_missing(typ int) bool {
	return typ >= ver.raw_ints.len - 1
}

fn (raw_ver RawVersion) coerce() ?Version {
	ver := raw_ver.complete()
	if !is_valid_number(ver.raw_ints[semver.ver_major]) {
		return error('Invalid major version: $ver.raw_ints[ver_major]')
	}
	return ver.to_version()
}

fn (raw_ver RawVersion) complete() RawVersion {
	mut raw_ints := raw_ver.raw_ints
	for raw_ints.len < 3 {
		raw_ints << '0'
	}
	return RawVersion{
		prerelease: raw_ver.prerelease
		metadata: raw_ver.metadata
		raw_ints: raw_ints
	}
}

fn (raw_ver RawVersion) validate() ?Version {
	if !raw_ver.is_valid() {
		return none
	}
	return raw_ver.to_version()
}

fn (raw_ver RawVersion) to_version() Version {
	return Version{raw_ver.raw_ints[semver.ver_major].int(), raw_ver.raw_ints[semver.ver_minor].int(), raw_ver.raw_ints[semver.ver_patch].int(), raw_ver.prerelease, raw_ver.metadata}
}