Class: Wrapture::RuleSpec

Inherits:
Object
  • Object
show all
Defined in:
lib/wrapture/rule_spec.rb

Overview

A condition (or set of conditions) that a struct or its members must meet in order to conform to a given specification. This allows a single struct type to be equivalent to some class specifications, but not others.

Constant Summary collapse

CONDITIONS =

A map of condition strings to their operators.

{ 'equals' => '==',
'greater-than' => '>',
'greater-than-equal' => '>=',
'less-than' => '<',
'less-than-equal' => '<=',
'not-equals' => '!=' }.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spec) ⇒ RuleSpec

Creates a rule spec based on the provided spec. Rules may be one of a number of different varieties.

Available conditions are available in the RuleSpec::CONDITIONS map, with the mapped values being the operate each one translates to.

For a rule that checks a struct member against a given value (a struct-member rule):

member-name

the name of the struct member the rule applies to

condition

the condition this rule uses

value

the value to use in the condition check

For a rule that compares two expressions against one another (an expression rule):

left-expression

the left expression in the comparison

condition

the condition this rule uses

right-expression

the right expression in the comparison



84
85
86
# File 'lib/wrapture/rule_spec.rb', line 84

def initialize(spec)
  @spec = RuleSpec.normalize_spec_hash(spec)
end

Class Method Details

.normalize_spec_hash(spec) ⇒ Object

Normalizes a hash specification of a rule. Normalization checks for invalid keys and unrecognized conditions.



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
# File 'lib/wrapture/rule_spec.rb', line 36

def self.normalize_spec_hash(spec)
  normalized = spec.dup

  required_keys = if spec.key?('member-name')
                    normalized['type'] = 'struct-member'
                    %w[member-name condition value].freeze
                  else
                    normalized['type'] = 'expression'
                    %w[left-expression condition right-expression].freeze
                  end

  missing_keys = required_keys - spec.keys
  unless missing_keys.empty?
    missing_msg = "required keys are missing: #{missing_keys.join(', ')}"
    raise(MissingSpecKey, missing_msg)
  end

  extra_keys = spec.keys - required_keys
  unless extra_keys.empty?
    extra_msg = "these keys are unrecognized: #{extra_keys.join(', ')}"
    raise(InvalidSpecKey, extra_msg)
  end

  unless RuleSpec::CONDITIONS.keys.include?(spec['condition'])
    condition_msg = "#{spec['condition']} is an invalid condition"
    raise(InvalidSpecKey, condition_msg)
  end

  normalized
end

Instance Method Details

#check(variable: nil, return_val: 'return_val') ⇒ Object

A string containing a check for a struct of the given name for this rule.

variable can be provided to provide the variable holding a struct pointer for struct-member rules.

return_val is used as the replacement for a return value signified by the use of RETURN_VALUE_KEYWORD in the spec. If not specified it defaults to 'return_val'. This parameter was added in release 0.4.2.



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/wrapture/rule_spec.rb', line 96

def check(variable: nil, return_val: 'return_val')
  condition = RuleSpec::CONDITIONS[@spec['condition']]

  if @spec['type'] == 'struct-member'
    "#{variable}->#{@spec['member-name']} #{condition} #{@spec['value']}"
  else
    left = @spec['left-expression']
    right = @spec['right-expression']
    "#{left} #{condition} #{right}".sub(RETURN_VALUE_KEYWORD, return_val)
  end
end

#use_return?Boolean

True if this rule requires a return value. This is equivalent to checking for the presence of RETURN_VALUE_KEYWORD in any of the expressions.

This method was added in release 0.4.2.

Returns:

  • (Boolean)


112
113
114
115
116
# File 'lib/wrapture/rule_spec.rb', line 112

def use_return?
  @spec['type'] == 'expression' &&
    [@spec['left-expression'],
     @spec['right-expression']].include?(RETURN_VALUE_KEYWORD)
end