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 |