Welcome to mirror list, hosted at ThFree Co, Russian Federation.

range.rb « relative_positioning « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 174d5ef4b3505f5e4abde27ccadc02b3ee3c6ef6 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
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