File: value.rb

package info (click to toggle)
ruby-kdl 1.0.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 480 kB
  • sloc: ruby: 6,667; yacc: 72; sh: 5; makefile: 4
file content (102 lines) | stat: -rw-r--r-- 2,267 bytes parent folder | download | duplicates (2)
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
module KDL
  class Value
    attr_reader :value, :format, :type

    def initialize(value, format: nil, type: nil)
      @value = value
      @format = format
      @type = type
    end

    def as_type(type, parser = nil)
      if parser.nil?
        self.class.new(value, format: format, type: type)
      else
        result = parser.call(self, type)
        return self.as_type(type) if result.nil?

        unless result.is_a?(::KDL::Value)
          raise ArgumentError, "expected parser to return an instance of ::KDL::Value, got `#{result.class}'"
        end

        result
      end
    end

    def to_s
      return stringify_value unless type

      "(#{StringDumper.stringify_identifier type})#{stringify_value}"
    end

    def stringify_value
      return format % value if format

      value.to_s
    end

    class Int < Value
      def ==(other)
        other.is_a?(Int) && value == other.value
      end
    end

    class Float < Value
      def ==(other)
        other.is_a?(Float) && value == other.value
      end

      def stringify_value
        return super.upcase unless value.is_a?(BigDecimal)

        sign, digits, _, exponent = value.split
        s = sign.negative? ? '-' : ''
        s += "#{digits[0]}.#{digits[1..-1]}"
        s += "E#{exponent.negative? ? '' : '+'}#{exponent - 1}"
        s
      end
    end

    class Boolean < Value
      def ==(other)
        other.is_a?(Boolean) && value == other.value
      end
    end

    class String < Value
      def stringify_value
        StringDumper.call(value)
      end

      def ==(other)
        other.is_a?(String) && value == other.value
      end
    end

    class NullImpl < Value
      def initialize(_=nil, format: nil, type: nil)
        super(nil, type: type)
      end

      def stringify_value
        "null"
      end

      def ==(other)
        other.is_a?(NullImpl)
      end
    end
    Null = NullImpl.new

    def self.from(value)
      case value
      when ::String then String.new(value)
      when Integer then Int.new(value)
      when ::Float then Float.new(value)
      when TrueClass, FalseClass then Boolean.new(value)
      when NilClass then Null
      else raise Error("Unsupported value type: #{value.class}")
      end
    end
  end
end