Sha256: efd797f57d84a119efde51f49e371df82b2a9881a279e72e5b4ab01daf0bdd6b

Contents?: true

Size: 1.63 KB

Versions: 4

Compression:

Stored size: 1.63 KB

Contents

#
#
#
class TypedStruct < Struct

  ## TODO: Compact syntax: "a,b,c:int x:string y:date"
  ## TODO: Optional commas separating fields: "a, b, c:int, d:bool"
  ## TODO: booleans fields add "field?" methods

  #
  # A perhaps-too-clever table of { "typename" => convert_proc } mappings.
  #
  CONVERTERS = Hash[ *{

    ["str", "string"]  => :passthru,
    ["int", "integer"] => proc { |me| me.to_i },
    ["hex"]            => proc { |me| me.to_i(16) },
    ["bool", "boolean"] => proc { |me| 
      case me
      when false, 0, "0", "off", "no",  "false", nil
        false
      when true,  1, "1", "on",  "yes", "true"
        true
      else
        raise "Invalid boolean type: #{me.inspect}"
      end
    },
    ["date", "time", "datetime"] => proc { |me| DateTime.parse me },
    ["timestamp"] => proc { |me| Time.at me },

  }.map { |names, converter| names.map { |n| [n, converter] } }.flatten ]

  #
  # Initialize a new struct.
  #
  def self.[](specs)
    # create [name,type] pairs
    pairs = specs.split.map do |spec|
      name, type = spec.split(":")

      type ||= "string"
      unless converter = CONVERTERS[type]
        raise "Unknown type: #{type}"
      end

      [name.to_sym, converter]
    end

    # initialize the C Struct
    struct = new(*pairs.transpose.first)

    # overload setter methods to call the proc
    pairs.each do |field, converter| 
      next if converter == :passthru
      struct.send(:define_method, "#{field}=") do |val|
        self[field] = ( val and converter.call val )
      end
    end

    struct
  end

  def initialize(*args)    
    members.zip(args).each { |field,value| send "#{field}=", value }
  end

end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
epitools-0.5.8 lib/epitools/typed_struct.rb
epitools-0.5.7 lib/epitools/typed_struct.rb
epitools-0.5.6 lib/epitools/typed_struct.rb
epitools-0.5.5 lib/epitools/typed_struct.rb