Skip to content

Commit

Permalink
factored out common code into abstract filter
Browse files Browse the repository at this point in the history
  • Loading branch information
mkristian committed Dec 8, 2012
1 parent 802edb0 commit 95ba112
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 143 deletions.
20 changes: 10 additions & 10 deletions lib/ixtlan/babel/deserializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,46 @@ def initialize(model_class)

private

def self.filter
@filter ||= HashFilter.new
def self.config
@config ||= FilterConfig.new
end

def filter
@filter ||= self.class.filter.dup
@filter ||= HashFilter.new
end

protected

def self.default_context_key(default)
filter.default_context_key(default)
config.default_context_key(default)
end

def self.add_context(key, options = {})
filter[key] = options
config[key] = options
end

public

def use(context_or_options)
filter.use(context_or_options)
@context_or_options = context_or_options
self
end

def from_array_hash( data )
if filter.root
data.collect{ |d| @model_class.new( filter.filter( d[ filter.root ] ) ) }
if self.class.config.root
data.collect{ |d| @model_class.new( filter.filter( d[ self.class.filter.root ] ) ) }
else
data.collect{ |d| @model_class.new( filter.filter( d ) ) }
end
end
private :from_array_hash

def from_hash(data, options = nil)
filter.use( options ) if options
filter.options = options if options
if data.is_a? Array
from_array_hash( data )
else
data = data[ filter.root ] if filter.root
data = data[ self.class.config.root ] if self.class.config.root
@model_class.new( filter.filter( data ) )
end
end
Expand Down
62 changes: 17 additions & 45 deletions lib/ixtlan/babel/filter_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@
module Ixtlan
module Babel
class FilterConfig

def initialize(context_or_options = nil)
use(context_or_options)
end

private

def context
@context ||= {}
end

public

def add_custom_serializers( map )
@map = map
def context_options( context_or_options )
if context_or_options
case context_or_options
when Symbol
if opts = context[ context_or_options ]
opts.dup
end
when Hash
context_or_options
end
end
end

public

def default_context_key( single = :single,
collection = :collection )
@single, @collection = single, collection
Expand All @@ -32,48 +37,15 @@ def []( key )
context[ key.to_sym ] if key
end

def use( context_or_options )
if context_or_options
case context_or_options
when Symbol
if opts = context[ context_or_options ]
@options = opts.dup
end
when Hash
@options = context_or_options
end
else
@options = nil
end
self
end

def single_options
@options || context[default_context_key[0]] || {}
def single_options( context_or_options )
context_options( context_or_options ) || context[default_context_key[0]] || {}
end

def collection_options
@options || context[default_context_key[1]] || {}
def collection_options( context_or_options )
context_options( context_or_options ) || context[default_context_key[1]] || {}
end

attr_accessor :root
def root
@root ||= single_options.key?(:root) ? single_options[:root].to_s : nil
end

private

def options_for( data )
@options || (data.is_a?(Array) ? collection_options : single_options)
end

def serialize( data )
if @map && ser = @map[ data.class.to_s ]
ser.call(data)
else
data
end
end

end
end
Expand Down
81 changes: 6 additions & 75 deletions lib/ixtlan/babel/hash_filter.rb
Original file line number Diff line number Diff line change
@@ -1,78 +1,17 @@
require 'ixtlan/babel/context'
require 'ixtlan/babel/abstract_filter'
module Ixtlan
module Babel
class HashFilter
class HashFilter < AbstractFilter

def initialize(context_or_options = nil)
use(context_or_options)
end

private

def context
@context ||= {}
end

public

def add_custom_serializers( map )
@map = map
end

def default_context_key( single = :single,
collection = :collection )
@single, @collection = single, collection
end

def []=( key, options )
context[ key.to_sym ] = options if key
end

def []( key )
context[ key.to_sym ] if key
end

def use( context_or_options )
if context_or_options
case context_or_options
when Symbol
if opts = context[ context_or_options ]
@options = opts.dup
end
when Hash
@options = context_or_options
end
else
@options = nil
def filter( data )
if data
filter_data( data,
Context.new( options ) )
end
self
end

def filter( hash = {} )
if hash
filter_data( hash,
Context.new( options_for( hash ) ) )
end
end

def single_options
@options || context[default_context_key[0]] || {}
end

def collection_options
@options || context[default_context_key[1]] || {}
end

def root
@root ||= single_options.key?(:root) ? single_options[:root].to_s : nil
end

private

def options_for( hash )
@options || (hash.is_a?(Array) ? collection_options : single_options)
end

def filter_array( array, options )
array.collect do |item|
if item.is_a?( Array ) || item.is_a?( Hash )
Expand All @@ -83,14 +22,6 @@ def filter_array( array, options )
end
end

def serialize( data )
if @map && ser = @map[ data.class.to_s ]
ser.call(data)
else
data
end
end

def filter_data( data, context )
result = {}
data.each do |k,v|
Expand Down
5 changes: 3 additions & 2 deletions lib/ixtlan/babel/model_filter.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
require 'ixtlan/babel/abstract_filter'
module Ixtlan
module Babel
class ModelFilter < HashFilter
class ModelFilter < AbstractFilter

def filter( model, &block )
if model
data = block.call( model )
filter_data( model, data,
Context.new( options_for( data ) ),
Context.new( options ),
&block )
end
end
Expand Down
23 changes: 12 additions & 11 deletions lib/ixtlan/babel/serializer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'ixtlan/babel/hash_filter'
require 'ixtlan/babel/model_filter'
require 'ixtlan/babel/filter_config'
module Ixtlan
module Babel
class Serializer
Expand Down Expand Up @@ -30,12 +31,12 @@ def add_custom_serializers(map)

private

def self.filter
@filter ||= ModelFilter.new
def self.config
@config ||= FilterConfig.new
end

def filter
@filter ||= @model_or_models.is_a?( Hash ) ? HashFilter.new : self.class.filter.dup
@filter ||= @model_or_models.is_a?( Hash ) ? HashFilter.new : ModelFilter.new
end

protected
Expand All @@ -52,17 +53,17 @@ def self.model_name
end

def self.default_context_key(single = :single, collection = :collection)
filter.default_context_key(single, collection)
config.default_context_key(single, collection)
end

def self.add_context(key, options = {})
filter[key] = options
config[key] = options
end

public

def use(context_or_options)
filter.use(context_or_options)
def use( context_or_options )
@context_or_options = context_or_options
self
end

Expand All @@ -83,11 +84,11 @@ def to_json(options = nil)

def setup_filter(options)
o = if collection?
filter.collection_options.dup.merge!( options || {} )
self.class.config.collection_options( @context_or_options )
else
filter.single_options.dup.merge!( options || {} )
self.class.config.single_options( @context_or_options )
end
filter.use( o )
filter.options = o.merge!( options || {} )
end
private :setup_filter

Expand Down Expand Up @@ -122,7 +123,7 @@ def attr(model)
private

def filter_model( model )
if root = filter.single_options[:root]
if root = self.class.config.root
{root.to_s => filter.filter( model ){ |model| attr(model) } }
else
filter.filter( model ){ |model| attr(model) }
Expand Down

0 comments on commit 95ba112

Please sign in to comment.