File: params.rb

package info (click to toggle)
ruby-bindata 2.4.14-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 600 kB
  • sloc: ruby: 8,566; makefile: 4
file content (128 lines) | stat: -rw-r--r-- 3,742 bytes parent folder | download
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
116
117
118
119
120
121
122
123
124
125
126
127
128
require 'bindata/lazy'

module BinData
  module AcceptedParametersPlugin
    # Mandatory parameters must be present when instantiating a data object.
    def mandatory_parameters(*args)
      accepted_parameters.mandatory(*args)
    end

    # Optional parameters may be present when instantiating a data object.
    def optional_parameters(*args)
      accepted_parameters.optional(*args)
    end

    # Default parameters can be overridden when instantiating a data object.
    def default_parameters(*args)
      accepted_parameters.default(*args)
    end

    # Mutually exclusive parameters may not all be present when
    # instantiating a data object.
    def mutually_exclusive_parameters(*args)
      accepted_parameters.mutually_exclusive(*args)
    end

    alias mandatory_parameter mandatory_parameters
    alias optional_parameter  optional_parameters
    alias default_parameter   default_parameters

    def accepted_parameters #:nodoc:
      @accepted_parameters ||= begin
        ancestor_params = superclass.respond_to?(:accepted_parameters) ?
                            superclass.accepted_parameters : nil
        AcceptedParameters.new(ancestor_params)
      end
    end

    # BinData objects accept parameters when initializing.  AcceptedParameters
    # allow a BinData class to declaratively identify accepted parameters as
    # mandatory, optional, default or mutually exclusive.
    class AcceptedParameters
      def initialize(ancestor_parameters = nil)
        if ancestor_parameters
          @mandatory = ancestor_parameters.mandatory.dup
          @optional  = ancestor_parameters.optional.dup
          @default   = ancestor_parameters.default.dup
          @mutually_exclusive = ancestor_parameters.mutually_exclusive.dup
        else
          @mandatory = []
          @optional  = []
          @default   = Hash.new
          @mutually_exclusive = []
        end
      end

      def mandatory(*args)
        unless args.empty?
          @mandatory.concat(to_syms(args))
          @mandatory.uniq!
        end
        @mandatory
      end

      def optional(*args)
        unless args.empty?
          @optional.concat(to_syms(args))
          @optional.uniq!
        end
        @optional
      end

      def default(args = nil)
        if args
          to_syms(args.keys)  # call for side effect of validating names
          args.each_pair do |param, value|
            @default[param.to_sym] = value
          end
        end
        @default
      end

      def mutually_exclusive(*args)
        arg1 = args.shift
        until args.empty?
          args.each do |arg2|
            @mutually_exclusive.push([arg1.to_sym, arg2.to_sym])
            @mutually_exclusive.uniq!
          end
          arg1 = args.shift
        end
        @mutually_exclusive
      end

      def all
        (@mandatory + @optional + @default.keys).uniq
      end

      #---------------
      private

      def to_syms(args)
        syms = args.collect(&:to_sym)
        ensure_valid_names(syms)
        syms
      end

      def ensure_valid_names(names)
        invalid_names = self.class.invalid_parameter_names
        names.each do |name|
          if invalid_names.include?(name)
            raise NameError.new("Rename parameter '#{name}' " \
                                "as it shadows an existing method.", name)
          end
        end
      end

      def self.invalid_parameter_names
        @invalid_names ||= begin
          all_names = LazyEvaluator.instance_methods(true)
          allowed_names = [:name, :type]
          invalid_names = (all_names - allowed_names).uniq

          Hash[*invalid_names.collect { |key| [key.to_sym, true] }.flatten]
        end
      end
    end
  end
end