class Dependabot::Uv::Version

def self.correct?(version)

def self.correct?(version)
  return false if version.nil?
  version.to_s.match?(ANCHORED_VERSION_PATTERN)
end

def self.new(version)

def self.new(version)
  T.cast(super, Dependabot::Uv::Version)
end

def <=>(other)

def <=>(other)
  other = Dependabot::Uv::Version.new(other.to_s) unless other.is_a?(Dependabot::Uv::Version)
  other = T.cast(other, Dependabot::Uv::Version)
  epoch_comparison = epoch <=> other.epoch
  return epoch_comparison unless epoch_comparison.zero?
  release_comparison = release_version_comparison(other)
  return release_comparison unless release_comparison.zero?
  pre_comparison = compare_keys(pre_cmp_key, other.pre_cmp_key)
  return pre_comparison unless pre_comparison.zero?
  post_comparison = compare_keys(post_cmp_key, other.post_cmp_key)
  return post_comparison unless post_comparison.zero?
  dev_comparison = compare_keys(dev_cmp_key, other.dev_cmp_key)
  return dev_comparison unless dev_comparison.zero?
  compare_keys(local_cmp_key, other.local_cmp_key)
end

def compare_keys(key, other_key)

def compare_keys(key, other_key)
  if key.is_a?(Integer) && other_key.is_a?(Integer)
    key <=> other_key
  elsif key.is_a?(Array) && other_key.is_a?(Array)
    key <=> other_key
  elsif key.is_a?(Integer)
    key == NEGATIVE_INFINITY ? -1 : 1
  elsif other_key.is_a?(Integer)
    other_key == NEGATIVE_INFINITY ? 1 : -1
  end
end

def dev_cmp_key

def dev_cmp_key
  # Versions without a dev segment should sort after those with one.
  return INFINITY if dev.nil?
  T.must(dev)
end

def ignored_major_versions

def ignored_major_versions
  version_parts = release_segment # e.g [1,2,3] if version is 1.2.3-alpha3
  lower_parts = [version_parts[0].to_i + 1] + [lowest_prerelease_suffix] # earliest next major version prerelease
  lower_bound = ">= #{lower_parts.join('.')}"
  [lower_bound]
end

def ignored_minor_versions

def ignored_minor_versions
  parts = release_segment # e.g [1,2,3] if version is 1.2.3-alpha3
  version_parts = parts.fill(0, parts.length...2)
  lower_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + [lowest_prerelease_suffix]
  upper_parts = version_parts.first(0) + [version_parts[0].to_i + 1] + [lowest_prerelease_suffix]
  lower_bound = ">= #{lower_parts.join('.')}"
  upper_bound = "< #{upper_parts.join('.')}"
  ["#{lower_bound}, #{upper_bound}"]
end

def ignored_patch_versions

def ignored_patch_versions
  parts = release_segment # e.g [1,2,3] if version is 1.2.3-alpha3
  version_parts = parts.fill(0, parts.length...2)
  upper_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + [lowest_prerelease_suffix]
  lower_bound = "> #{self}"
  upper_bound = "< #{upper_parts.join('.')}"
  ["#{lower_bound}, #{upper_bound}"]
end

def initialize(version)

def initialize(version)
  raise Dependabot::BadRequirementError, "Malformed version string - string is nil" if version.nil?
  @version_string = version.to_s
  raise Dependabot::BadRequirementError, "Malformed version string - string is empty" if @version_string.empty?
  matches = ANCHORED_VERSION_PATTERN.match(@version_string.downcase)
  unless matches
    raise Dependabot::BadRequirementError,
          "Malformed version string - #{@version_string} does not match regex"
  end
  @epoch = matches["epoch"].to_i
  @release_segment = matches["release"]&.split(".")&.map(&:to_i) || []
  @pre = parse_letter_version(matches["pre_l"], matches["pre_n"])
  @post = parse_letter_version(matches["post_l"], matches["post_n1"] || matches["post_n2"])
  @dev = parse_letter_version(matches["dev_l"], matches["dev_n"])
  @local = parse_local_version(matches["local"])
  super(matches["release"] || "")
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  "#<#{self.class} #{@version_string}>"
end

def local_cmp_key

def local_cmp_key
  if local.nil?
    # Versions without a local segment should sort before those with one.
    NEGATIVE_INFINITY
  else
    # According to PEP440.
    # - Alphanumeric segments sort before numeric segments
    # - Alphanumeric segments sort lexicographically
    # - Numeric segments sort numerically
    # - Shorter versions sort before longer versions when the prefixes match exactly
    local&.map do |token|
      if token.is_a?(Integer)
        [token, ""]
      else
        [NEGATIVE_INFINITY, token]
      end
    end
  end
end

def lowest_prerelease_suffix

def lowest_prerelease_suffix
  "dev0"
end

def pad_for_comparison(tokens, other_tokens)

def pad_for_comparison(tokens, other_tokens)
  tokens = tokens.dup
  other_tokens = other_tokens.dup
  longer = [tokens, other_tokens].max_by(&:count)
  shorter = [tokens, other_tokens].min_by(&:count)
  difference = T.must(longer).length - T.must(shorter).length
  difference.times { T.must(shorter) << 0 }
  [tokens, other_tokens]
end

def parse_letter_version(letter = nil, number = nil)

def parse_letter_version(letter = nil, number = nil)
  return if letter.nil? && number.nil?
  if letter
    # Implicit 0 for cases where prerelease has no numeral
    number ||= 0
    # Normalize alternate spellings
    if letter == "alpha"
      letter = "a"
    elsif letter == "beta"
      letter = "b"
    elsif %w(c pre preview).include? letter
      letter = "rc"
    elsif %w(rev r).include? letter
      letter = "post"
    end
    return letter, number.to_i
  end
  # Number but no letter i.e. implicit post release syntax (e.g. 1.0-1)
  letter = "post"
  [letter, number.to_i]
end

def parse_local_version(local)

def parse_local_version(local)
  return if local.nil?
  # Takes a string like abc.1.twelve and turns it into ["abc", 1, "twelve"]
  local.split(/[\._-]/).map { |s| /^\d+$/.match?(s) ? s.to_i : s }
end

def post_cmp_key

def post_cmp_key
  # Versions without a post segment should sort before those with one.
  return NEGATIVE_INFINITY if post.nil?
  T.must(post)
end

def pre_cmp_key

def pre_cmp_key
  if pre.nil? && post.nil? && dev # sort 1.0.dev0 before 1.0a0
    NEGATIVE_INFINITY
  elsif pre.nil?
    INFINITY # versions without a pre-release should sort after those with one.
  else
    T.must(pre)
  end
end

def prerelease?

def prerelease?
  !!(pre || dev)
end

def release

def release
  Dependabot::Uv::Version.new(release_segment.join("."))
end

def release_version_comparison(other)

def release_version_comparison(other)
  tokens, other_tokens = pad_for_comparison(release_segment, other.release_segment)
  tokens <=> other_tokens
end

def to_s

def to_s
  @version_string
end