configfiles 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/configfiles-example.rb +86 -0
  2. data/lib/configfiles.rb +108 -0
  3. metadata +63 -0
@@ -0,0 +1,86 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+
3
+ require 'pp'
4
+ require 'ipaddr'
5
+ require 'configfiles'
6
+
7
+ class MyConfig < ConfigFiles::Base
8
+
9
+ class MyException < Exception; end
10
+ class MyArgumentError < ArgumentError; end
11
+
12
+ # I find more rubystic defining a "conversion"
13
+ # rater than statically declaring classes ;)
14
+ parameter :par_integer, :to_i
15
+ parameter :par_str # no conversion needed
16
+ parameter :par_custom do |s|
17
+ s.length
18
+ end
19
+
20
+ # receive an Enumerator from Parser, and turn into another Enumerator
21
+ #
22
+ # NOTE: Enumerable#map_enum would be cool ;-)
23
+ #
24
+ # TODO: use facets Enumerable#defer? Mmm, let's try to depend
25
+ # just on the std lib if possible...
26
+ #
27
+ enumerator :iplist do |ipstr|
28
+ IPAddr.new(ipstr)
29
+ end
30
+
31
+ validate do |data|
32
+ raise MyArgumentError if data[:par_custom] > 100
33
+ raise MyException unless data[:par_str] =~ /\S+/
34
+ # or you may use standard exceptions....
35
+ true
36
+ end
37
+
38
+ end
39
+
40
+ class MyKeyValueParser
41
+
42
+ include ConfigFiles::Parser
43
+
44
+ def self.read(io, opt_h={})
45
+ h = {}
46
+ io.each_line do |line|
47
+ key_re = '[\w\d_\-\.]+'
48
+ value_re = '[\w\d_\-\.]+'
49
+ if line =~ /(#{key_re})\s*=\s*(#{value_re})/
50
+ h[$1.to_sym] = $2
51
+ end
52
+ end
53
+ return h
54
+ end
55
+ end
56
+
57
+
58
+ class MyListSlurper
59
+
60
+ include ConfigFiles::Parser
61
+
62
+ def self.read(io, opt_h={})
63
+ if block_given?
64
+ io.each_line do |line|
65
+ yield line.strip if line =~ /\S/
66
+ end
67
+ else
68
+ enum_for :read, io
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+
75
+
76
+ c = MyConfig.new
77
+
78
+ parse_result = MyKeyValueParser.read(File.open 'keyval.conf')
79
+
80
+ c.load parse_result
81
+
82
+ pp c
83
+
84
+
85
+
86
+
@@ -0,0 +1,108 @@
1
+ # Copyright 2010, Guido De Rosa <guido.derosa*vemarsas.it>
2
+ # License: same of Ruby
3
+
4
+
5
+
6
+ module ConfigFiles
7
+
8
+ VERSION = 0.0.1
9
+
10
+ module Parser
11
+ def self.read_file(path)
12
+ self.read File.open path
13
+ end
14
+ end
15
+
16
+ class Base
17
+
18
+ class ArgumentError < ::ArgumentError; end
19
+ class RuntimeError < ::RuntimeError; end
20
+
21
+ @@parameters ||= {}
22
+ @@options ||= {}
23
+
24
+ # examples:
25
+ # on :unknown_parameter, :fail | :accept | :ignore
26
+ # on :unknown_parameter, {|str| str.to_i}
27
+ #
28
+ def self.on(name, value=nil, &block)
29
+ if block
30
+ @@options[name] = block
31
+ elsif name == :unknown_parameter and value == :accept
32
+ @@options[name] = lambda {|x| x}
33
+ else
34
+ @@options[name] = value
35
+ end
36
+ end
37
+
38
+ def self.option(name)
39
+ @@options[name]
40
+ end
41
+
42
+ def self.parameter(name, converter=nil, &converter_block)
43
+ if converter
44
+ if converter_block
45
+ raise ArgumentError, 'you must either specify a symbol or a block'
46
+ else
47
+ converter_block = lambda {|x| x.method(converter).call}
48
+ end
49
+ else
50
+ converter_block ||= lambda {|x| x}
51
+ end
52
+ @@parameters[name] = {
53
+ :converter => converter_block
54
+ }
55
+ end
56
+
57
+ # A special kind of parameter, with a special kind of converter, which in turn
58
+ # converts an Enumerator of Strings into an Enumerator of custom objects.
59
+ # Working with Enumerators instead of
60
+ # Arrays is the right thing to do when you deal with very long list of
61
+ # names, IP adresses, URIs etc.
62
+ def self.enumerator(name, &block)
63
+ parameter name do |enum|
64
+ Enumerator.new do |yielder|
65
+ enum.each do |string|
66
+ yielder << block.call(string)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def self.validate(&block)
73
+ @@validate = block
74
+ end
75
+
76
+ attr_accessor :options, :data
77
+
78
+ def initialize
79
+ @options = @@options.dup
80
+ @data = {}
81
+ def @data.missing_method(id); @data[id]; end
82
+ end
83
+
84
+ def validate
85
+ @@validate.call(@data)
86
+ end
87
+
88
+ def load(h)
89
+ h.each_pair do |id, value|
90
+ if @@parameters[id][:converter]
91
+ @data[id] = @@parameters[id][:converter].call(value)
92
+ elsif @options[:unknown_parameter] == :fail
93
+ raise RuntimeError, "unknown parameter #{key}" # otherwise ignore
94
+ elsif @options[:unknown_parameter].respond_to? :call
95
+ block = @options[:unknown_parameter]
96
+ @data[id] = block.call value
97
+ end
98
+ end
99
+ validate
100
+ end
101
+
102
+ def flush
103
+ @data = {}
104
+ end
105
+
106
+ end
107
+
108
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configfiles
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Guido De Rosa
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-03 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: "A simple library to specify the format of configuration files and the way to turn them into Ruby objects. Ruby1.9 centric. It supports lazy lists. No write support: it's strongly sugested to use ERB or other templating systems for that."
22
+ email: guido.derosa@vemarsas.it
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - configfiles-example.rb
31
+ - lib/configfiles.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/gderosa/configfiles
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.6
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: A simple library to specify the format of configuration files and the way to turn them into Ruby objects.
62
+ test_files: []
63
+