Class: JsonMessage

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

Defined Under Namespace

Classes: Error, Field, ParseError, ValidationError

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fields = {}) ⇒ JsonMessage

Returns a new instance of JsonMessage.



108
109
110
111
# File 'lib/json_message.rb', line 108

def initialize(fields={})
  @msg = {}
  fields.each {|k, v| set_field(k, v)}
end

Class Attribute Details

.fieldsObject (readonly)

Returns the value of attribute fields.



40
41
42
# File 'lib/json_message.rb', line 40

def fields
  @fields
end

Class Method Details

.decode(json) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/json_message.rb', line 46

def decode(json)
  begin
    dec_json = Yajl::Parser.parse(json)
  rescue => e
    raise ParseError, e.to_s
  end

  from_decoded_json(dec_json)
end

.from_decoded_json(dec_json) ⇒ Object

Raises:



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
# File 'lib/json_message.rb', line 56

def from_decoded_json(dec_json)
  raise ParseError, "Decoded JSON cannot be nil" unless dec_json

  errs = {}

  # Treat null values as if the keys aren't present. This isn't as strict as one would like,
  # but conforms to typical use cases.
  dec_json.delete_if {|k, v| v == nil}

  # Collect errors by field
  @fields.each do |name, field|
    err = nil
    name_s = name.to_s
    if dec_json.has_key?(name_s)
      err = field.schema.validate(dec_json[name_s])
    elsif field.required
      err = "Missing field #{name}"
    end
    errs[name] = err if err
  end

  raise ValidationError.new(errs) unless errs.empty?

  new(dec_json)
end

.optional(field_name, schema = JsonSchema::WILDCARD) ⇒ Object



86
87
88
# File 'lib/json_message.rb', line 86

def optional(field_name, schema=JsonSchema::WILDCARD)
  define_field(field_name, schema, false)
end

.required(field_name, schema = JsonSchema::WILDCARD) ⇒ Object



82
83
84
# File 'lib/json_message.rb', line 82

def required(field_name, schema=JsonSchema::WILDCARD)
  define_field(field_name, schema, true)
end

.schema(&blk) ⇒ Object



42
43
44
# File 'lib/json_message.rb', line 42

def schema(&blk)
  instance_eval &blk
end

Instance Method Details

#encodeObject



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/json_message.rb', line 113

def encode
  if self.class.fields
    missing_fields = {}
    self.class.fields.each do |name, field|
      missing_fields[name] = "Missing field #{name}" unless (!field.required || @msg.has_key?(name))
    end
    raise ValidationError.new(missing_fields) unless missing_fields.empty?
  end

  Yajl::Encoder.encode(@msg)
end

#extractObject



125
126
127
# File 'lib/json_message.rb', line 125

def extract
  @msg.dup.freeze
end