summaryrefslogtreecommitdiff
path: root/lib/gitlab/relative_positioning/range.rb
blob: 0b0ccdf5be474b766008986f5deedc118db73d10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# frozen_string_literal: true

module Gitlab
  module RelativePositioning
    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

    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