File: field_parser.rb

package info (click to toggle)
ruby-rgfa 1.3.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 824 kB
  • sloc: ruby: 5,649; makefile: 9
file content (115 lines) | stat: -rw-r--r-- 3,335 bytes parent folder | download | duplicates (4)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
require "json"
require_relative "byte_array"
require_relative "numeric_array"
require_relative "cigar"
require_relative "error"
require_relative "field_array"

#
# Methods to parse the string representations of the GFA fields
# @api private
#
module RGFA::FieldParser

  # Parse a string representation of a GFA field value
  # @raise [RGFA::Error] if the value is not valid
  # @param datatype [RGFA::Line::FIELD_DATATYPE]
  def parse_gfa_field(datatype: nil,
                      validate_strings: true,
                      fieldname: nil,
                      frozen: false)
    case datatype
    when :cmt
      return self
    when :A, :Z, :seq
      validate_gfa_field!(datatype, fieldname: fieldname) if validate_strings
      self.freeze if frozen
      return self
    when :lbl
      validate_segment_name!
      validate_gfa_field!(datatype, fieldname: fieldname) if validate_strings
      return to_sym.freeze
    when :orn
      validate_gfa_field!(datatype, fieldname: fieldname) if validate_strings
      return to_sym.freeze
    when :i
      return Integer(self)
    when :pos
      value = Integer(self)
      raise RGFA::FieldParser::FormatError if value < 0
      return value
    when :f
      return Float(self)
    when :H
      value = to_byte_array
      value.freeze if frozen
      return value
    when :B
      value = to_numeric_array
      value.freeze if frozen
      return value
    when :J
      value = JSON.parse(self)
      # RGFA convention for array of fields
      if value.kind_of?(Array) and value.rgfa_field_array?
        value = value.to_rgfa_field_array
      end
      # no need to freeze, as any Hash or Array will be valid
      return value
    when :cig
      value = to_cigar
      value.freeze if frozen
      return value
    when :cgs
      value = split(",").map do |c|
        c = c.to_cigar
        c.freeze if frozen
        c
      end
      value.freeze if frozen
      return value
    when :lbs
      value = split(",").map do |l|
        o = l[-1].to_sym
        l = l[0..-2]
        if validate_strings
          l.validate_gfa_field!(:lbl, fieldname: "#{fieldname} "+
                               "(entire field content: #{self})" )
        end
        os = [l.to_sym, o].to_oriented_segment
        os.freeze if frozen
        os
      end
      value.freeze if frozen
      return value
    else
      raise RGFA::FieldParser::UnknownDatatypeError,
        "Datatype unknown: #{datatype.inspect}"
    end
  end

  # Parses an optional field in the form tagname:datatype:value
  # and parses the value according to the datatype
  # @raise [RGFA::FieldParser::FormatError] if the string does not represent
  #   an optional field
  # @return [Array(Symbol, RGFA::Line::FIELD_DATATYPE, String)]
  #   the parsed content of the field
  def parse_gfa_optfield
    if self =~ /^([A-Za-z][A-Za-z0-9]):([AifZJHB]):(.+)$/
      return $1.to_sym, $2.to_sym, $3
    else
      raise RGFA::FieldParser::FormatError,
        "Expected optional field, found: #{self.inspect}"
    end
  end
end

# Error raised if the field content has an invalid format
class RGFA::FieldParser::FormatError < RGFA::Error; end

# Error raised if an unknown datatype symbol is used
class RGFA::FieldParser::UnknownDatatypeError < RGFA::Error; end

class String
  include RGFA::FieldParser
end