diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /lib/gitlab/relative_positioning/range.rb | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) | |
download | gitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz |
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'lib/gitlab/relative_positioning/range.rb')
-rw-r--r-- | lib/gitlab/relative_positioning/range.rb | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/gitlab/relative_positioning/range.rb b/lib/gitlab/relative_positioning/range.rb new file mode 100644 index 00000000000..174d5ef4b35 --- /dev/null +++ b/lib/gitlab/relative_positioning/range.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module Gitlab + module RelativePositioning + IllegalRange = Class.new(ArgumentError) + + class Range + attr_reader :lhs, :rhs + + def open_on_left? + lhs.nil? + end + + def open_on_right? + rhs.nil? + end + + def cover?(item_context) + return false unless item_context + return false unless item_context.positioned? + return true if item_context.object == lhs&.object + return true if item_context.object == rhs&.object + + pos = item_context.relative_position + + return lhs.relative_position < pos if open_on_right? + return pos < rhs.relative_position if open_on_left? + + lhs.relative_position < pos && pos < rhs.relative_position + end + + def ==(other) + other.is_a?(RelativePositioning::Range) && lhs == other.lhs && rhs == other.rhs + end + end + + def self.range(lhs, rhs) + if lhs && rhs + ClosedRange.new(lhs, rhs) + elsif lhs + StartingFrom.new(lhs) + elsif rhs + EndingAt.new(rhs) + else + raise IllegalRange, 'One of rhs or lhs must be provided' unless lhs && rhs + end + end + + class ClosedRange < RelativePositioning::Range + def initialize(lhs, rhs) + @lhs, @rhs = lhs, rhs + raise IllegalRange, 'Either lhs or rhs is missing' unless lhs && rhs + raise IllegalRange, 'lhs and rhs cannot be the same object' if lhs == rhs + end + end + + class StartingFrom < RelativePositioning::Range + include Gitlab::Utils::StrongMemoize + + def initialize(lhs) + @lhs = lhs + raise IllegalRange, 'lhs is required' unless lhs + end + + def rhs + strong_memoize(:rhs) { lhs.rhs_neighbour } + end + end + + class EndingAt < RelativePositioning::Range + include Gitlab::Utils::StrongMemoize + + def initialize(rhs) + @rhs = rhs + raise IllegalRange, 'rhs is required' unless rhs + end + + def lhs + strong_memoize(:lhs) { rhs.lhs_neighbour } + end + end + end +end |