line.rb 2.2 KB
Newer Older
1 2 3
module Gitlab
  module Diff
    class Line
Felipe Artur's avatar
Felipe Artur committed
4
      attr_reader :line_code, :type, :index, :old_pos, :new_pos
5
      attr_writer :rich_text
6
      attr_accessor :text
7

Felipe Artur's avatar
Felipe Artur committed
8
      def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil)
9
        @text, @type, @index = text, type, index
10
        @old_pos, @new_pos = old_pos, new_pos
Sean McGivern's avatar
Sean McGivern committed
11
        @parent_file = parent_file
Felipe Artur's avatar
Felipe Artur committed
12 13 14 15

        # When line code is not provided from cache store we build it
        # using the parent_file(Diff::File or Conflict::File).
        @line_code = line_code || calculate_line_code
16
      end
17

18
      def self.init_from_hash(hash)
Felipe Artur's avatar
Felipe Artur committed
19
        new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code])
20 21 22
      end

      def serialize_keys
Felipe Artur's avatar
Felipe Artur committed
23
        @serialize_keys ||= %i(line_code text type index old_pos new_pos)
24 25 26 27
      end

      def to_hash
        hash = {}
28
        serialize_keys.each { |key| hash[key] = send(key) } # rubocop:disable GitlabSecurity/PublicSend
29 30 31
        hash
      end

32 33 34 35 36 37 38 39
      def old_line
        old_pos unless added? || meta?
      end

      def new_line
        new_pos unless removed? || meta?
      end

40 41 42 43
      def line
        new_line || old_line
      end

44 45 46 47
      def unchanged?
        type.nil?
      end

48
      def added?
49
        %w[new new-nonewline].include?(type)
50 51 52
      end

      def removed?
53
        %w[old old-nonewline].include?(type)
54 55
      end

56
      def meta?
57
        %w[match new-nonewline old-nonewline].include?(type)
58
      end
59

60 61 62 63
      def match?
        type == :match
      end

64
      def discussable?
65 66 67 68
        !meta?
      end

      def rich_text
Felipe Artur's avatar
Felipe Artur committed
69
        @parent_file.try(:highlight_lines!) if @parent_file && !@rich_text
70 71

        @rich_text
72 73
      end

Felipe Artur's avatar
Felipe Artur committed
74 75 76 77 78 79 80 81 82
      def meta_positions
        return unless meta?

        {
          old_pos: old_pos,
          new_pos: new_pos
        }
      end

83 84
      def as_json(opts = nil)
        {
Felipe Artur's avatar
Felipe Artur committed
85
          line_code: line_code,
86 87 88 89
          type: type,
          old_line: old_line,
          new_line: new_line,
          text: text,
Felipe Artur's avatar
Felipe Artur committed
90 91
          rich_text: rich_text || text,
          meta_data: meta_positions
92 93
        }
      end
Felipe Artur's avatar
Felipe Artur committed
94 95 96 97 98 99

      private

      def calculate_line_code
        @parent_file&.line_code(self)
      end
100 101 102
    end
  end
end