module OStruct::Sanitizer

Provides a series of sanitization rules to be applied on OpenStruct fields on a Rails-ish fashion.

@example

class Person < OpenStruct
  include OStruct::Sanitizer

  truncate :name, length: 20
  alphanumeric :name
  sanitize :middle_name do |value|
    # Perform a more complex sanitization process
  end
end

Constants

VERSION

Public Class Methods

included(base) click to toggle source
# File lib/ostruct/sanitizer.rb, line 20
def self.included(base)
  unless base.ancestors.include? OpenStruct
    raise "#{self.name} can only be used within OpenStruct classes"
  end

  base.extend ClassMethods
end
new(attrs = {}) click to toggle source

Initializes the OpenStruct applying any registered sanitization rules

Calls superclass method
# File lib/ostruct/sanitizer.rb, line 30
def initialize(attrs = {})
  super nil
  attrs.each_pair do |field, value|
    self[field] = value
  end
end

Public Instance Methods

[]=(name, value) click to toggle source

Set attribute's value via setter so that any existing sanitization rules may be applied

@param [Symbol|String] name the attribute's name @param [Any] value the attribute's value

# File lib/ostruct/sanitizer.rb, line 64
def []=(name, value)
  send("#{name}=", value)
end
method_missing(method, *args) click to toggle source

Creates a setter method for the corresponding field which applies any existing sanitization rules

@param [Symbol] method the missing method @param [Array<Any>] args the method's arguments list

Calls superclass method
# File lib/ostruct/sanitizer.rb, line 43
def method_missing(method, *args)
  # Give OpenStruct a chance to create getters and setters for the
  # corresponding field
  super method, *args

  if field = setter?(method)
    # override setter logic to apply any existing sanitization rules before
    # assigning the new value to the field
    override_setter_for(field) if sanitize?(field)
    # uses the newly created setter to set the field's value and apply any
    # existing sanitization rules
    send(method, args[0])
  end
end

Private Instance Methods

override_setter_for(field) click to toggle source
# File lib/ostruct/sanitizer.rb, line 74
def override_setter_for(field)
  define_singleton_method("#{field}=") do |value|
    modifiable?[field] = sanitize(field, value)
  end
end
sanitize(field, value) click to toggle source
# File lib/ostruct/sanitizer.rb, line 80
def sanitize(field, value)
  return value if value.nil?
  self.class.sanitizers[field].reduce(value) do |current_value, sanitizer|
    sanitizer.call(current_value)
  end
end
sanitize?(field) click to toggle source
# File lib/ostruct/sanitizer.rb, line 87
def sanitize?(field)
  self.class.sanitizers.key? field
end
setter?(method) click to toggle source
# File lib/ostruct/sanitizer.rb, line 70
def setter?(method)
  method[/.*(?==\z)/m].to_s.to_sym
end