func (v Version) String() string {
	return v.raw
}
String returns version as string
package version
import (
	"errors"
	"regexp"
	"strconv"
	"strings"
)
type Version struct {
	raw        string
	slice      [3]int
	preRelease string
	build      string
	size       int
}
var (
	ErrEmpty = errors.New("Version can't be empty")
	ErrEmptyBuild = errors.New("Build number is empty")
	ErrEmptyPrerelease = errors.New("Prerelease number is empty")
)
var preRegExp = regexp.MustCompile(`([a-zA-Z-.]{1,})([0-9]{0,})`)
func Parse(v string) (Version, error) {
	if v == "" {
		return Version{}, ErrEmpty
	}
	var slice = [3]int{0, 0, 0}
	var raw = v
	var (
		preRelease string
		build      string
		size       int
	)
	if strings.Contains(v, "+") {
		bs := strings.Split(v, "+")
		if bs[1] == "" {
			return Version{}, ErrEmptyBuild
		}
		v = bs[0]
		build = bs[1]
	}
	if strings.Contains(v, "-") {
		ps := strings.Split(v, "-")
		if ps[1] == "" {
			return Version{}, ErrEmptyPrerelease
		}
		v = ps[0]
		preRelease = ps[1]
	}
	for index, version := range strings.Split(v, ".") {
		if index < 3 {
			iv, err := strconv.Atoi(version)
			if err != nil {
				return Version{}, err
			}
			slice[index] = iv
			size = index + 1
		}
	}
	return Version{
		raw:        raw,
		slice:      slice,
		preRelease: preRelease,
		build:      build,
		size:       size,
	}, nil
}
func (v Version) Major() int {
	if v.raw == "" || len(v.slice) == 0 {
		return -1
	}
	return v.slice[0]
}
func (v Version) Minor() int {
	if v.raw == "" || len(v.slice) == 0 {
		return -1
	}
	return v.slice[1]
}
func (v Version) Patch() int {
	if v.raw == "" || len(v.slice) == 0 {
		return -1
	}
	return v.slice[2]
}
func (v Version) PreRelease() string {
	if v.raw == "" {
		return ""
	}
	return v.preRelease
}
func (v Version) Build() string {
	if v.raw == "" {
		return ""
	}
	return v.build
}
func (v Version) Simple() string {
	if v.raw == "" || len(v.slice) == 0 {
		return "0.0.0"
	}
	return strconv.Itoa(v.slice[0]) + "." + strconv.Itoa(v.slice[1]) + "." + strconv.Itoa(v.slice[2])
}
func (v Version) Equal(version Version) bool {
	if v.Major() != version.Major() {
		return false
	}
	if v.Minor() != version.Minor() {
		return false
	}
	if v.Patch() != version.Patch() {
		return false
	}
	if v.PreRelease() != version.PreRelease() {
		return false
	}
	if v.Build() != version.Build() {
		return false
	}
	return true
}
func (v Version) Less(version Version) bool {
	if v.Int() < version.Int() {
		return true
	}
	pr1, pr2 := v.PreRelease(), version.PreRelease()
	if pr1 != pr2 {
		return prereleaseLess(pr1, pr2)
	}
	return false
}
func (v Version) Greater(version Version) bool {
	if v.Int() > version.Int() {
		return true
	}
	pr1, pr2 := v.PreRelease(), version.PreRelease()
	if pr1 != pr2 {
		return !prereleaseLess(pr1, pr2)
	}
	return false
}
func (v Version) Contains(version Version) bool {
	if v.Major() != version.Major() {
		return false
	}
	if v.size == 1 {
		return true
	}
	if v.Minor() != version.Minor() {
		return false
	}
	if v.size == 2 {
		return true
	}
	if v.Patch() != version.Patch() {
		return false
	}
	return false
}
func (v Version) Int() int {
	result := v.Major() * 1000000
	result += v.Minor() * 1000
	result += v.Patch()
	return result
}
func (v Version) IsZero() bool {
	return v.raw == ""
}