format_engine 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f68de35267cd2cec34ca42b8638cc5035f64ff42
4
- data.tar.gz: d0c21b2ba3cd709f75d9e8e036d5848238abbafa
3
+ metadata.gz: 53a90dc85e96a48d8f1b469ef5749f63102a4230
4
+ data.tar.gz: 6555ef6261b11cd7feb5fe996b3e5143d593271b
5
5
  SHA512:
6
- metadata.gz: 493f6d819bb9c0ceae8eb2c743c5d99a7d0d3fadc537e69e90e540e06c688e3f303a417f5fd8da9174419a8febac8d65ef21209398cc66c27867ee1de325f212
7
- data.tar.gz: 25823819e6fc80c713e1f95cfb0fcd25c3b9bf9034cf7eb0755865217a43a77ebbc6ee0a68dc55ceb22225b9ca1bb234b37fb2e6e64d610ce765546a55a0ce00
6
+ metadata.gz: 9bd665882c88cdb9ed4acb2e6bed688a3b69585630a74425e2fc14e15a098ebb36899dd609d1c5680ffcb89a68c61390ee808dbfb4535837624f4945fa26c636
7
+ data.tar.gz: a726f4166591fe0683275b35eec562e4d4f9baadbdbe8f14c41e780736add9b38922941e4efedce6ffcc2e853fd3cec9bb5a1b5398d7d0fe32a21e72d88221eb
data/README.md CHANGED
@@ -21,10 +21,22 @@ Or install it yourself as:
21
21
 
22
22
  ## Usage
23
23
 
24
+ In general formatters and parsers are defined using the attr_formatter
25
+ and attr_parser methods. Both of these methods accept a symbol and a hash of
26
+ strings (plus a few special symbols) that point to blocks (that take no arguments).
27
+
28
+ The symbol is the name of a method that is created. The hash forms a library
29
+ of supported formats. Special hash keys are the symbols :before (that is run
30
+ before all other operations) and :after (that is run after all other operations)
31
+
32
+ ### Example
33
+ The following example is found in the mocks folder:
34
+
24
35
  ```ruby
25
36
  require 'format_engine'
26
37
 
27
38
  #A demo class for the format_engine gem.
39
+
28
40
  class Customer
29
41
  extend FormatEngine::AttrFormatter
30
42
  extend FormatEngine::AttrParser
@@ -35,10 +47,12 @@ class Customer
35
47
  #Demo customer last name
36
48
  attr_reader :last_name
37
49
 
50
+ #Demo defn of the strfmt method for formatted string output!
38
51
  attr_formatter :strfmt,
39
52
  {"%f" => lambda {cat src.first_name.ljust(fmt.width) },
40
53
  "%l" => lambda {cat src.last_name.ljust(fmt.width) } }
41
54
 
55
+ #Demo defn of the strprs method for formatted string input!
42
56
  attr_parser :strprs,
43
57
  {"%f" => lambda { hsh[:fn] = found if parse(/(\w)+/ ) },
44
58
  "%l" => lambda { hsh[:ln] = found if parse(/(\w)+/ ) },
@@ -63,6 +77,77 @@ agent = Customer.strprs(in_str, "%f, %l")
63
77
  #Etc, etc, etc ...
64
78
 
65
79
  ```
80
+ ## Format Specification
81
+
82
+ Format String Specification Syntax (BNF):
83
+
84
+ * spec = { text | item }+
85
+ * item = "%" {flag}* {parm {"." parm}?}? {command}
86
+ * flag = { "~" | "@" | "#" | "&" | "^" |
87
+ "&" | "*" | "-" | "+" | "=" |
88
+ "?" | "_" | "<" | ">" | "\\" |
89
+ "/" | "." | "," | "|" | "!" }
90
+ * parm = { "0" .. "9" }+
91
+ * command = { "a" .. "z" | "A" .. "Z" }
92
+
93
+
94
+ ###Sample:
95
+
96
+ The format specification "Elapsed = %*02H:%M:%5.2S!"
97
+ creates the following format specification array:
98
+
99
+ ```ruby
100
+ [Literal("Elapsed = "),
101
+ Variable("%*H", ["02"]),
102
+ Literal("H"),
103
+ Variable("%M", nil).
104
+ Literal(":"),
105
+ Variable("%S", ["5", "2"]),
106
+ Literal("!")]
107
+ ```
108
+ Where literals are processed as themselves and variables are executed by looking
109
+ up the format string in the library and executing the corresponding block.
110
+
111
+ **Note:** If a format string does not correspond to an entry in the library,
112
+ an exception occurs.
113
+
114
+ ## Formatting / Parsing Blocks
115
+
116
+ In the context of a formatting / parsing block, the
117
+ "self" of that block is an instance of SpecInfo. The
118
+ components of that object are:
119
+
120
+ ###When Formatting:
121
+ Attributes:
122
+ * src - The object that is the source of the data (RO).
123
+ * dst - A string that receives the formatted output (RO).
124
+ * fmt - The format specification currently being processed (RW).
125
+ * engine - The formatting engine. Mostly for access to the library (RO).
126
+ * hsh - A utility hash so that the formatting process can retain state (RO).
127
+
128
+ Methods
129
+ * cat - Append the string that follows to the formatted output. This is
130
+ equivalent to dst << "string"
131
+
132
+ ###When Parsing:
133
+ Attributes:
134
+ * src - A string that is the source of formatted input (RO).
135
+ * dst - The class of the object being created (RO).
136
+ * fmt - The parse specification currently being processed (RW).
137
+ * engine - The parsing engine. Mostly for access to the library (RO).
138
+ * hsh - A utility hash so that the parsing process can retain state RO.
139
+
140
+ Methods
141
+ * set - Set the return value of the parsing operation to the value that follows.
142
+ * parse - Look for the string or regex parm that follows. Return the data found or nil.
143
+ * parse! - Like parse but raises an exception (with optional msg) if not found.
144
+ * found? - Did the last parse succeed?
145
+ * found - The text found by the last parse (or parse!) operation.
146
+
147
+ ###Format Specifier Attributes
148
+ The format specifier (accessed as fmt above) has the following attributes:
149
+ * width - The width parameter or 0 if not specified.
150
+ * prec - The precision parameter or 0 if not specified.
66
151
 
67
152
  ## Philosophy
68
153
 
@@ -70,7 +155,7 @@ When designing this gem, a concerted effort has been applied to keeping it as
70
155
  simple as possible. To this end, many subtle programming techniques have been
71
156
  avoided in favor of simpler, more obvious approaches. This is based on the
72
157
  observation that I don't trust code that I don't understand and I avoid code
73
- I don't trust.
158
+ that I don't trust.
74
159
 
75
160
  Feedback on the convenience/clarity balance as well as any other topics are
76
161
  most welcomed.
@@ -20,9 +20,7 @@ module FormatEngine
20
20
  engine = Engine.new(library)
21
21
 
22
22
  define_method(method) do |spec_str|
23
- spec = FormatEngine::FormatSpec.get_spec(spec_str)
24
-
25
- engine.do_format(self, spec)
23
+ engine.do_format(self, spec_str)
26
24
  end
27
25
 
28
26
  end
@@ -21,9 +21,7 @@ module FormatEngine
21
21
  engine = Engine.new(library)
22
22
 
23
23
  define_singleton_method(method) do |src, spec_str|
24
- spec = FormatEngine::FormatSpec.get_spec(spec_str)
25
-
26
- engine.do_parse(src, self, spec)
24
+ engine.do_parse(src, self, spec_str)
27
25
  end
28
26
 
29
27
  end
@@ -18,40 +18,48 @@ module FormatEngine
18
18
  @lib[index]
19
19
  end
20
20
 
21
+ # Set an entry in the library
22
+ def []=(index, value)
23
+ @lib[index] = value
24
+ end
25
+
21
26
  #Do the actual work of building the formatted output.
22
27
  #<br>Parameters
23
28
  #* src - The source object being formatted.
24
- #* format_spec - The format specification.
25
- def do_format(src, format_spec)
26
- due_process(src, "", format_spec, :do_format)
29
+ #* format_spec_str - The format specification string.
30
+ def do_format(src, format_spec_str)
31
+ spec_info = SpecInfo.new(src, "", nil, self, {})
32
+
33
+ due_process(spec_info, format_spec_str) do |fmt|
34
+ fmt.do_format(spec_info)
35
+ end
27
36
  end
28
37
 
29
38
  #Do the actual work of parsing the formatted input.
30
39
  #<br>Parameters
31
40
  #* src - The source string being parsed.
32
41
  #* dst - The class of the object being created.
33
- #* format_spec - The format specification.
34
- def do_parse(*args)
35
- due_process(*args, :do_parse)
42
+ #* parse_spec_str - The format specification string.
43
+ def do_parse(src, dst, parse_spec_str)
44
+ spec_info = SpecInfo.new(src, dst, nil, self, {})
45
+
46
+ due_process(spec_info, parse_spec_str) do |fmt|
47
+ fmt.do_parse(spec_info)
48
+ end
36
49
  end
37
50
 
38
51
  #Do the actual work of parsing the formatted input.
39
52
  #<br>Parameters
40
- #* src - The input to the process.
41
- #* dst - The output of the process.
42
- #* format_spec - The format specification.
43
- #* sym - The symbol applied to each format specification.
44
- #<br>Endemic Code Smells
45
- #* :reek:LongParameterList
46
- def due_process(src, dst, format_spec, sym)
47
- spec_info = SpecInfo.new(src, dst, nil, self, {})
48
- spec_info.instance_exec(&self[:before])
49
-
50
- format_spec.validate(self).specs.each do |fmt|
51
- fmt.send(sym, spec_info)
52
- end
53
+ #* spec_info - The state of the process.
54
+ #* spec_str - The format specification string.
55
+ #* block - A code block performed for each format specification.
56
+ def due_process(spec_info, spec_str, &block)
57
+ spec = FormatSpec.get_spec(spec_str).validate(self)
53
58
 
59
+ spec_info.instance_exec(&self[:before])
60
+ spec.specs.each(&block)
54
61
  spec_info.instance_exec(&self[:after])
62
+
55
63
  spec_info.dst
56
64
  end
57
65
 
@@ -1,5 +1,5 @@
1
1
 
2
2
  module FormatEngine
3
3
  # The version of the format_engine gem.
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
@@ -28,7 +28,7 @@ class FormatterTester < Minitest::Test
28
28
  end
29
29
 
30
30
  def make_spec(str)
31
- FormatEngine::FormatSpec.get_spec str
31
+ str
32
32
  end
33
33
 
34
34
  def make_all(str)
@@ -60,7 +60,7 @@ class FormatterTester < Minitest::Test
60
60
  :before => lambda {dst << "((" },
61
61
  :after => lambda {dst << "))" })
62
62
 
63
- spec = FormatEngine::FormatSpec.get_spec "Test"
63
+ spec = "Test"
64
64
  assert_equal("((Test))", engine.do_format(nil, spec))
65
65
  end
66
66
 
@@ -68,4 +68,14 @@ class FormatterTester < Minitest::Test
68
68
  engine, obj, spec = make_all("Name = %f %j")
69
69
  assert_raises(RuntimeError) { engine.do_format(obj, spec) }
70
70
  end
71
+
72
+ def test_that_it_validates_before_before
73
+ engine, obj, spec = make_all("Name = %f %j")
74
+ test = 1
75
+ engine[:before] = lambda { test = 2 }
76
+
77
+ assert_raises(RuntimeError) { engine.do_format(obj, spec) }
78
+ assert_equal(1, test)
79
+ end
80
+
71
81
  end
@@ -29,7 +29,7 @@ class ParserTester < Minitest::Test
29
29
 
30
30
  def test_that_it_can_parse
31
31
  engine = make_parser
32
- spec = FormatEngine::FormatSpec.get_spec "%f, %l"
32
+ spec = "%f, %l"
33
33
  result = engine.do_parse("Squidly, Jones", TestPerson, spec)
34
34
 
35
35
  assert_equal(TestPerson, result.class)
@@ -39,7 +39,7 @@ class ParserTester < Minitest::Test
39
39
 
40
40
  def test_that_it_can_parse_loudly
41
41
  engine = make_parser
42
- spec = FormatEngine::FormatSpec.get_spec "%F, %L"
42
+ spec = "%F, %L"
43
43
  result = engine.do_parse("Squidly, Jones", TestPerson, spec)
44
44
 
45
45
  assert_equal(TestPerson, result.class)
@@ -49,7 +49,7 @@ class ParserTester < Minitest::Test
49
49
 
50
50
  def test_that_it_can_fix_shouting
51
51
  engine = make_parser
52
- spec = FormatEngine::FormatSpec.get_spec "%-F, %-L"
52
+ spec = "%-F, %-L"
53
53
  result = engine.do_parse("SQUIDLY, JONES", TestPerson, spec)
54
54
 
55
55
  assert_equal(TestPerson, result.class)
@@ -59,7 +59,7 @@ class ParserTester < Minitest::Test
59
59
 
60
60
  def test_that_it_can_flex_parse
61
61
  engine = make_parser
62
- spec = FormatEngine::FormatSpec.get_spec "%f%,s%l"
62
+ spec = "%f%,s%l"
63
63
  result = engine.do_parse("Squidly, Jones", TestPerson, spec)
64
64
 
65
65
  assert_equal(TestPerson, result.class)
@@ -69,7 +69,7 @@ class ParserTester < Minitest::Test
69
69
 
70
70
  def test_that_it_can_tab_parse
71
71
  engine = make_parser
72
- spec = FormatEngine::FormatSpec.get_spec "%f%t%l"
72
+ spec = "%f%t%l"
73
73
  result = engine.do_parse("Squidly\tJones", TestPerson, spec)
74
74
 
75
75
  assert_equal(TestPerson, result.class)
@@ -79,13 +79,13 @@ class ParserTester < Minitest::Test
79
79
 
80
80
  def test_that_it_can_detect_errors
81
81
  engine = make_parser
82
- spec = FormatEngine::FormatSpec.get_spec "%f, %l"
82
+ spec = "%f, %l"
83
83
 
84
84
  assert_raises(RuntimeError) do
85
85
  engine.do_parse("Squidly Jones", TestPerson, spec)
86
86
  end
87
87
 
88
- spec = FormatEngine::FormatSpec.get_spec "%f%!t%l"
88
+ spec = "%f%!t%l"
89
89
 
90
90
  assert_raises(RuntimeError) do
91
91
  engine.do_parse("Squidly Jones", TestPerson, spec)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: format_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Camilleri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-28 00:00:00.000000000 Z
11
+ date: 2015-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler