86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			V
		
	
	
| 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}
 | |
| }
 |