class VersionInterval

Attributes

end_cut[RW]
start_cut[RW]
type[RW]

Public Class Methods

new(type, start_cut, end_cut) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 12
def initialize(type, start_cut, end_cut)
  @type = type
  @start_cut = start_cut
  @end_cut = end_cut
end

Public Instance Methods

==(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 180
def ==(other_interval)
  @start_cut == other_interval.start_cut && @end_cut == other_interval.end_cut && @type == other_interval.type
end
bit_set?(interval_type) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 199
def bit_set?(interval_type)
  @type & interval_type != 0
end
collapse(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 45
def collapse(other_interval)
  return EmptyInterval.new if self.intersect(other_interval).instance_of?(EmptyInterval)

  frame = [@start_cut, other_interval.start_cut, @end_cut, other_interval.end_cut].reject { |cut| special(cut) }
  min_cut = frame.reduce { |smallest, current| smallest < current ? smallest : current }
  max_cut = frame.reduce { |biggest, current| biggest > current ? biggest : current }

  # compute the boundaries for the union
  type = compute_union_boundary(self, other_interval, min_cut, max_cut)
  VersionInterval.new(type, min_cut, max_cut)
end
cross_total() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 172
def cross_total
  if distinct?
    @start_cut.cross_total
  else
    @start_cut.cross_total + @end_cut.cross_total
  end
end
diff(other_interval, abs = true) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 150
def diff(other_interval, abs = true)
  if self.distinct? && other_interval.distinct?
    self.start_cut.diff(other_interval.start_cut, abs)
  else
    EmptyInterval.new()
  end
end
distinct?() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 102
def distinct?
  bit_set?(IntervalType::LEFT_CLOSED) && bit_set?(IntervalType::RIGHT_CLOSED) && @start_cut == @end_cut
end
empty?() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 142
def empty?
  self.instance_of?(EmptyInterval)
end
intersect(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 18
def intersect(other_interval)
  # this look odd -- we have to use it here though, because it may be that placeholders are present inside
  # the version for which > and < would yield true
  return EmptyInterval.new if !(@start_cut <= other_interval.end_cut) || !(other_interval.start_cut <= @end_cut)

  start_cut_new = max(@start_cut, other_interval.start_cut)
  end_cut_new = min(@end_cut, other_interval.end_cut)

  # compute the boundaries for the intersection
  type = compute_intersection_boundary(self, other_interval, start_cut_new, end_cut_new)
  interval = VersionInterval.new(type, start_cut_new, end_cut_new)
  half_open = !(interval.bit_set?(IntervalType::RIGHT_CLOSED) && interval.bit_set?(IntervalType::LEFT_CLOSED))

  interval.singleton? && half_open ? EmptyInterval.new : interval
end
invert() click to toggle source

inverts the given version interval – note that this function amy return two version intervals e.g., (2,10] -> (-inf, 2], (10, +inf)

left       right
# File lib/semver_dialects/semantic_version/version_interval.rb, line 187
def invert
  intervals = []
  left_type = bit_set?(IntervalType::LEFT_OPEN) ? IntervalType::RIGHT_CLOSED : IntervalType::RIGHT_OPEN
  left_type = left_type | IntervalType::LEFT_OPEN
  right_type = bit_set?(IntervalType::RIGHT_OPEN) ? IntervalType::LEFT_CLOSED : IntervalType::LEFT_OPEN
  right_type = right_type | IntervalType::RIGHT_OPEN

  intervals << VersionInterval.new(left_type, BelowAll.new, @start_cut) unless @start_cut.instance_of?(BelowAll)
  intervals << VersionInterval.new(right_type, @end_cut, AboveAll.new) unless @end_cut.instance_of?(AboveAll)
  intervals
end
join(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 162
def join(other_interval)
  if self.joinable?(other_interval)
    _join(self, other_interval)
  elsif other_interval.joinable?(self)
    _join(other_interval, self)
  else
    EmptyInterval.new()
  end
end
joinable?(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 158
def joinable?(other_interval)
  other_interval.start_cut.is_successor_of?(self.end_cut) || universal?
end
singleton?() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 146
def singleton?
  @start_cut == @end_cut && @start_cut.value == @end_cut.value
end
special(cut) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 57
def special(cut)
  cut.instance_of?(AboveAll) || cut.instance_of?(BelowAll)
end
subsumes?(other) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 106
def subsumes?(other)
  @start_cut <= other.start_cut && @end_cut >= other.end_cut
end
to_conan_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 126
def to_conan_s
  get_canoncial_s
end
to_description_s() click to toggle source

this function returns a human-readable descriptions of the version strings

# File lib/semver_dialects/semantic_version/version_interval.rb, line 72
def to_description_s
  s = ""
  if self.distinct?
    s = "version #{@start_cut.to_s}"
  elsif self.universal?
    s = "all versions "
  else
    s = "all versions "
    s += start_cut.instance_of?(BelowAll) ? "" : bit_set?(IntervalType::LEFT_OPEN) ? "after #{@start_cut.to_s} " : bit_set?(IntervalType::LEFT_CLOSED) ? "starting from #{@start_cut.to_s} " : ""
    s += end_cut.instance_of?(AboveAll) ? "" : bit_set?(IntervalType::RIGHT_OPEN) ? "before #{@end_cut.to_s}" : bit_set?(IntervalType::RIGHT_CLOSED) ? "up to #{@end_cut.to_s}" : ""
  end
  s.strip
end
to_gem_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 114
def to_gem_s
  get_canoncial_s
end
to_go_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 130
def to_go_s
  get_canoncial_s
end
to_maven_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 90
def to_maven_s
  s = ""
  # special case -- distinct version
  if self.distinct?
    s += "[#{@start_cut.to_s}]"
  else
    s += start_cut.instance_of?(BelowAll) ? "(," : bit_set?(IntervalType::LEFT_OPEN) ? "[#{@start_cut.to_s}," : bit_set?(IntervalType::LEFT_CLOSED) ? "[#{@start_cut.to_s}," : ""
    s += end_cut.instance_of?(AboveAll) ? ")" : bit_set?(IntervalType::RIGHT_OPEN) ? "#{@end_cut.to_s})" : bit_set?(IntervalType::RIGHT_CLOSED) ? "#{@end_cut.to_s}]" : ""
  end
  s
end
to_npm_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 122
def to_npm_s
  get_canoncial_s
end
to_nuget_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 86
def to_nuget_s
  to_maven_s
end
to_packagist_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 138
def to_packagist_s
  get_canoncial_s(',')
end
to_pypi_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 134
def to_pypi_s
  get_canoncial_s(',', '==')
end
to_ruby_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 118
def to_ruby_s
  get_canoncial_s
end
to_s() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 61
def to_s
  s = ""
  s += bit_set?(IntervalType::LEFT_CLOSED) ? "[" : ""
  s += bit_set?(IntervalType::LEFT_OPEN) ? "(" : ""
  s += [@start_cut, @end_cut].join(",")
  s += bit_set?(IntervalType::RIGHT_CLOSED) ? "]" : ""
  s += bit_set?(IntervalType::RIGHT_OPEN) ? ")" : ""
  s
end
union(other_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 34
def union(other_interval)
  return EmptyInterval.new if self.intersect(other_interval).instance_of?(EmptyInterval)

  start_cut_new = min(@start_cut, other_interval.start_cut)
  end_cut_new = max(@end_cut, other_interval.end_cut)

  # compute the boundaries for the union
  type = compute_union_boundary(self, other_interval, start_cut_new, end_cut_new)
  VersionInterval.new(type, start_cut_new, end_cut_new)
end
universal?() click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 110
def universal?
  (bit_set?(IntervalType::LEFT_OPEN) && bit_set?(IntervalType::RIGHT_OPEN) && @start_cut.instance_of?(BelowAll) && @end_cut.instance_of?(AboveAll)) || @start_cut.is_initial_version? && @end_cut.instance_of?(AboveAll)
end

Protected Instance Methods

_join(first_interval, second_interval) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 244
def _join(first_interval, second_interval)
  if first_interval.joinable?(second_interval)
    VersionInterval.new(first_interval.type, first_interval.start_cut.dup, second_interval.end_cut.dup)
  else
    EmptyInterval.new()
  end
end
compute_boundary(interval_a, interval_b, start_cut_new, end_cut_new, left_check, right_check) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 214
def compute_boundary(interval_a, interval_b, start_cut_new, end_cut_new, left_check, right_check)
  start_cut_a = interval_a.start_cut
  end_cut_a = interval_a.end_cut
  type_a = interval_a.type

  start_cut_b = interval_b.start_cut
  end_cut_b = interval_b.end_cut
  type_b = interval_b.type

  left_fill = left_check == IntervalType::LEFT_OPEN ? IntervalType::LEFT_CLOSED : IntervalType::LEFT_OPEN
  right_fill = right_check == IntervalType::RIGHT_OPEN ? IntervalType::RIGHT_CLOSED : IntervalType::RIGHT_OPEN

  # compute the boundaries for the union
  if start_cut_b == start_cut_a && start_cut_b == start_cut_b
    one_left_closed = left_type(type_a) == left_check || left_type(type_b) == left_check
    left_type = one_left_closed ? left_check : left_fill
  else
    left_type = start_cut_new == start_cut_a ? left_type(type_a) : left_type(type_b)
  end

  if end_cut_b == end_cut_a && end_cut_b == end_cut_b
    one_right_closed = right_type(type_a) == right_check || right_type(type_b) == right_check
    right_type = one_right_closed ? right_check : right_fill
  else
    right_type = end_cut_new == end_cut_a ? right_type(type_a) : right_type(type_b)
  end

  left_type | right_type
end
compute_intersection_boundary(interval_a, interval_b, start_cut_new, end_cut_new) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 210
def compute_intersection_boundary(interval_a, interval_b, start_cut_new, end_cut_new)
  compute_boundary(interval_a, interval_b,start_cut_new, end_cut_new, IntervalType::LEFT_OPEN, IntervalType::RIGHT_OPEN)
end
compute_union_boundary(interval_a, interval_b, start_cut_new, end_cut_new) click to toggle source

computes the boundary type for union operation

# File lib/semver_dialects/semantic_version/version_interval.rb, line 206
def compute_union_boundary(interval_a, interval_b, start_cut_new, end_cut_new)
  compute_boundary(interval_a, interval_b, start_cut_new, end_cut_new, IntervalType::LEFT_CLOSED, IntervalType::RIGHT_CLOSED)
end
get_canoncial_s(delimiter = " ", eq = '=') click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 252
def get_canoncial_s(delimiter = " ", eq = '=')
  if self.distinct?
    "#{eq}#{@start_cut.to_s}"
  else
    first = start_cut.instance_of?(BelowAll) ? "" : bit_set?(IntervalType::LEFT_OPEN) ? ">#{@start_cut.to_s}" : bit_set?(IntervalType::LEFT_CLOSED) ? ">=#{@start_cut.to_s}" : ""
    second = end_cut.instance_of?(AboveAll) ? "" : bit_set?(IntervalType::RIGHT_OPEN) ? "<#{@end_cut.to_s}" : bit_set?(IntervalType::RIGHT_CLOSED) ? "<=#{@end_cut.to_s}" : ""
    !first.empty? && !second.empty? ? "#{first}#{delimiter}#{second}" : first + second
  end
end
left_type(type) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 274
def left_type(type)
  (IntervalType::LEFT_OPEN | IntervalType::LEFT_CLOSED) & type
end
max(cut_a, cut_b) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 262
def max(cut_a, cut_b)
  cut_a > cut_b ? cut_a : cut_b
end
min(cut_a, cut_b) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 266
def min(cut_a, cut_b)
  cut_a < cut_b ? cut_a : cut_b
end
right_type(type) click to toggle source
# File lib/semver_dialects/semantic_version/version_interval.rb, line 270
def right_type(type)
  (IntervalType::RIGHT_OPEN | IntervalType::RIGHT_CLOSED) & type
end