diff options
Diffstat (limited to 'v_windows/v/old/vlib/semver/range.v')
-rw-r--r-- | v_windows/v/old/vlib/semver/range.v | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/v_windows/v/old/vlib/semver/range.v b/v_windows/v/old/vlib/semver/range.v new file mode 100644 index 0000000..fd0a769 --- /dev/null +++ b/v_windows/v/old/vlib/semver/range.v @@ -0,0 +1,252 @@ +module semver + +// * Private functions. +const ( + comparator_sep = ' ' + comparator_set_sep = ' || ' + hyphen_range_sep = ' - ' + x_range_symbols = 'Xx*' +) + +enum Operator { + gt + lt + ge + le + eq +} + +struct Comparator { + ver Version + op Operator +} + +struct ComparatorSet { + comparators []Comparator +} + +struct Range { + comparator_sets []ComparatorSet +} + +struct InvalidComparatorCountError { + msg string + code int +} + +struct InvalidComparatorFormatError { + msg string + code int +} + +fn (r Range) satisfies(ver Version) bool { + mut final_result := false + for set in r.comparator_sets { + final_result = final_result || set.satisfies(ver) + } + return final_result +} + +fn (set ComparatorSet) satisfies(ver Version) bool { + for comp in set.comparators { + if !comp.satisfies(ver) { + return false + } + } + return true +} + +fn (c Comparator) satisfies(ver Version) bool { + if c.op == .gt { + return ver.gt(c.ver) + } + if c.op == .lt { + return ver.lt(c.ver) + } + if c.op == .ge { + return ver.ge(c.ver) + } + if c.op == .le { + return ver.le(c.ver) + } + if c.op == .eq { + return ver.eq(c.ver) + } + return false +} + +fn parse_range(input string) ?Range { + raw_comparator_sets := input.split(semver.comparator_set_sep) + mut comparator_sets := []ComparatorSet{} + for raw_comp_set in raw_comparator_sets { + if can_expand(raw_comp_set) { + s := expand_comparator_set(raw_comp_set) or { return err } + comparator_sets << s + } else { + s := parse_comparator_set(raw_comp_set) or { return err } + comparator_sets << s + } + } + return Range{comparator_sets} +} + +fn parse_comparator_set(input string) ?ComparatorSet { + raw_comparators := input.split(semver.comparator_sep) + if raw_comparators.len > 2 { + return IError(&InvalidComparatorFormatError{ + msg: 'Invalid format of comparator set for input "$input"' + }) + } + mut comparators := []Comparator{} + for raw_comp in raw_comparators { + c := parse_comparator(raw_comp) or { + return IError(&InvalidComparatorFormatError{ + msg: 'Invalid comparator "$raw_comp" in input "$input"' + }) + } + comparators << c + } + return ComparatorSet{comparators} +} + +fn parse_comparator(input string) ?Comparator { + mut op := Operator.eq + mut raw_version := '' + if input.starts_with('>=') { + op = .ge + raw_version = input[2..] + } else if input.starts_with('<=') { + op = .le + raw_version = input[2..] + } else if input.starts_with('>') { + op = .gt + raw_version = input[1..] + } else if input.starts_with('<') { + op = .lt + raw_version = input[1..] + } else if input.starts_with('=') { + raw_version = input[1..] + } else { + raw_version = input + } + version := coerce_version(raw_version) or { return none } + return Comparator{version, op} +} + +fn parse_xrange(input string) ?Version { + mut raw_ver := parse(input).complete() + for typ in versions { + if raw_ver.raw_ints[typ].index_any(semver.x_range_symbols) == -1 { + continue + } + match typ { + ver_major { + raw_ver.raw_ints[ver_major] = '0' + raw_ver.raw_ints[ver_minor] = '0' + raw_ver.raw_ints[ver_patch] = '0' + } + ver_minor { + raw_ver.raw_ints[ver_minor] = '0' + raw_ver.raw_ints[ver_patch] = '0' + } + ver_patch { + raw_ver.raw_ints[ver_patch] = '0' + } + else {} + } + } + if !raw_ver.is_valid() { + return none + } + return raw_ver.to_version() +} + +fn can_expand(input string) bool { + return input[0] == `~` || input[0] == `^` || input.contains(semver.hyphen_range_sep) + || input.index_any(semver.x_range_symbols) > -1 +} + +fn expand_comparator_set(input string) ?ComparatorSet { + match input[0] { + `~` { return expand_tilda(input[1..]) } + `^` { return expand_caret(input[1..]) } + else {} + } + if input.contains(semver.hyphen_range_sep) { + return expand_hyphen(input) + } + return expand_xrange(input) +} + +fn expand_tilda(raw_version string) ?ComparatorSet { + min_ver := coerce_version(raw_version) or { return none } + mut max_ver := min_ver + if min_ver.minor == 0 && min_ver.patch == 0 { + max_ver = min_ver.increment(.major) + } else { + max_ver = min_ver.increment(.minor) + } + return make_comparator_set_ge_lt(min_ver, max_ver) +} + +fn expand_caret(raw_version string) ?ComparatorSet { + min_ver := coerce_version(raw_version) or { return none } + mut max_ver := min_ver + if min_ver.major == 0 { + max_ver = min_ver.increment(.minor) + } else { + max_ver = min_ver.increment(.major) + } + return make_comparator_set_ge_lt(min_ver, max_ver) +} + +fn expand_hyphen(raw_range string) ?ComparatorSet { + raw_versions := raw_range.split(semver.hyphen_range_sep) + if raw_versions.len != 2 { + return none + } + min_ver := coerce_version(raw_versions[0]) or { return none } + raw_max_ver := parse(raw_versions[1]) + if raw_max_ver.is_missing(ver_major) { + return none + } + mut max_ver := raw_max_ver.coerce() or { return none } + if raw_max_ver.is_missing(ver_minor) { + max_ver = max_ver.increment(.minor) + return make_comparator_set_ge_lt(min_ver, max_ver) + } + return make_comparator_set_ge_le(min_ver, max_ver) +} + +fn expand_xrange(raw_range string) ?ComparatorSet { + min_ver := parse_xrange(raw_range) or { return none } + if min_ver.major == 0 { + comparators := [ + Comparator{min_ver, Operator.ge}, + ] + return ComparatorSet{comparators} + } + mut max_ver := min_ver + if min_ver.minor == 0 { + max_ver = min_ver.increment(.major) + } else { + max_ver = min_ver.increment(.minor) + } + return make_comparator_set_ge_lt(min_ver, max_ver) +} + +fn make_comparator_set_ge_lt(min Version, max Version) ComparatorSet { + comparators := [ + Comparator{min, Operator.ge}, + Comparator{max, Operator.lt}, + ] + return ComparatorSet{comparators} +} + +fn make_comparator_set_ge_le(min Version, max Version) ComparatorSet { + comparators := [ + Comparator{min, Operator.ge}, + Comparator{max, Operator.le}, + ] + return ComparatorSet{comparators} +} |