edn 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -42,9 +42,9 @@ By default, this will work for strings, symbols, numbers, arrays, hashes, sets,
42
42
 
43
43
  In **edn**, you have _keywords_, which look like Ruby symbols and have the same meaning and purpose. These are converted to Ruby symbols.
44
44
 
45
- You have **edn** _symbols_, which generally reflect variable names, but have several purposes. We parse these and return `EDN::Type::Symbol` values for them, as they are not directly portable into Ruby.
45
+ You have **edn** _symbols_, which generally reflect variable names, but have several purposes. We parse these and return `EDN::Type::Symbol` values for them, as they are not directly portable into Ruby. To create an **edn** symbol in Ruby, call `EDN::Type::Symbol.new` or `EDN.symbol` with a string argument, or use the convenience unary operator `~` like so: `~"elf/rings"`.
46
46
 
47
- You have _vectors_, which map to Ruby arrays, and _lists_, which are linked lists in Clojure. We map these to `EDN::Type::List` values, which are type-compatible with arrays.
47
+ You have _vectors_, which map to Ruby arrays, and _lists_, which are linked lists in Clojure. We map these to `EDN::Type::List` values, which are type-compatible with arrays. To create an **edn** list in Ruby, call `EDN::Type::List.new` or `EDN.list` with all arguments to go in the list. If you have an array, you will use the splat operator, like so: `EDN.list(*[1, 2, 3])`. You can also use the `~` unary operator like so: `~[1, 2, 3]`.
48
48
 
49
49
  **edn** has character types, but Ruby does not. These are converted into one-character strings.
50
50
 
@@ -126,5 +126,5 @@ This method calls `.to_edn` on the second argument and joins the arguments appro
126
126
  4. Push to the branch (`git push origin my-new-feature`)
127
127
  5. Create new Pull Request
128
128
 
129
- [edn]: https://github.com/richhickey/edn
130
- [README]: https://github.com/richhickey/edn/blob/master/README.md
129
+ [edn]: https://github.com/edn-format/edn
130
+ [README]: https://github.com/edn-format/edn/blob/master/README.md
data/lib/edn.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  $:.push(File.dirname(__FILE__))
2
- require "edn/version"
3
- require "edn/core_ext"
4
- require "edn/parser"
5
- require "edn/transform"
2
+ require 'edn/version'
3
+ require 'edn/types'
4
+ require 'edn/core_ext'
5
+ require 'edn/parser'
6
+ require 'edn/transform'
6
7
 
7
8
  module EDN
8
9
  @parser = EDN::Parser.new
@@ -31,7 +32,7 @@ module EDN
31
32
  @tags[tag] = nil
32
33
  end
33
34
 
34
- def self.tag_value(tag, value)
35
+ def self.tagged_value(tag, value)
35
36
  func = @tags[tag]
36
37
  if func
37
38
  func.call(value)
@@ -43,6 +44,14 @@ module EDN
43
44
  def self.tagout(tag, value)
44
45
  ["##{tag}", value.to_edn].join(" ")
45
46
  end
47
+
48
+ def self.symbol(text)
49
+ EDN::Type::Symbol.new(text)
50
+ end
51
+
52
+ def self.list(*values)
53
+ EDN::Type::List.new(*values)
54
+ end
46
55
  end
47
56
 
48
57
  EDN.register("inst") do |value|
data/lib/edn/core_ext.rb CHANGED
@@ -22,6 +22,10 @@ module EDN
22
22
  end
23
23
 
24
24
  module String
25
+ def ~@
26
+ EDN::Type::Symbol.new(self)
27
+ end
28
+
25
29
  def to_edn
26
30
  self.inspect
27
31
  end
@@ -34,6 +38,10 @@ module EDN
34
38
  end
35
39
 
36
40
  module Array
41
+ def ~@
42
+ EDN::Type::List.new(*self)
43
+ end
44
+
37
45
  def to_edn
38
46
  '[' + self.map(&:to_edn).join(" ") + ']'
39
47
  end
data/lib/edn/parser.rb CHANGED
@@ -1,5 +1,30 @@
1
1
  require 'parslet'
2
2
 
3
+ class IgnoreParslet < Parslet::Atoms::Base
4
+ def initialize(parslet)
5
+ @parslet = parslet
6
+ end
7
+ def to_s_inner(prec)
8
+ @parslet.to_s(prec)
9
+ end
10
+ def try(source, context)
11
+ success, value = result = @parslet.try(source, context)
12
+
13
+ return succ(nil) if success
14
+ return result
15
+ end
16
+ end
17
+
18
+ module IgnoreDSL
19
+ def ignore
20
+ IgnoreParslet.new(self)
21
+ end
22
+ end
23
+
24
+ class Parslet::Atoms::Base
25
+ include IgnoreDSL
26
+ end
27
+
3
28
  module EDN
4
29
  class Parser < Parslet::Parser
5
30
  root(:top)
@@ -28,13 +53,14 @@ module EDN
28
53
  }
29
54
 
30
55
  rule(:tagged_value) {
31
- tag >> space >> base_value.as(:value)
56
+ tag >> space? >> base_value.as(:value)
32
57
  }
33
58
 
34
59
  # Collections
35
60
 
36
61
  rule(:vector) {
37
62
  str('[') >>
63
+ space? >>
38
64
  top.repeat.as(:vector) >>
39
65
  space? >>
40
66
  str(']')
@@ -105,7 +131,7 @@ module EDN
105
131
  # Parts
106
132
 
107
133
  rule(:tag) {
108
- str('#') >> symbol.as(:tag)
134
+ str('#') >> match['[:alpha:]'].present? >> symbol.as(:tag)
109
135
  }
110
136
 
111
137
  rule(:symbol_chars) {
@@ -131,8 +157,18 @@ module EDN
131
157
  match['0-9']
132
158
  }
133
159
 
160
+ rule(:newline) { str("\r").maybe >> str("\n") }
161
+
162
+ rule(:comment) {
163
+ str(';') >> (newline.absent? >> any).repeat
164
+ }
165
+
166
+ rule(:discard) {
167
+ str('#_') >> space? >> (tagged_value | base_value).ignore
168
+ }
169
+
134
170
  rule(:space) {
135
- match('[\s,]').repeat(1)
171
+ (discard | comment | match['\s,']).repeat(1)
136
172
  }
137
173
 
138
174
  rule(:space?) { space.maybe }
data/lib/edn/transform.rb CHANGED
@@ -37,7 +37,7 @@ module EDN
37
37
  rule(:map => subtree(:array)) { Hash[array.map { |hash| [hash[:key], hash[:value]] }] }
38
38
 
39
39
  rule(:tag => simple(:tag), :value => subtree(:value)) {
40
- EDN.tag_value(tag.to_s, value)
40
+ EDN.tagged_value(tag.to_s, value)
41
41
  }
42
42
  end
43
43
  end
data/lib/edn/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module EDN
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.2"
3
3
  end
@@ -5,12 +5,38 @@ describe EDN::Parser do
5
5
 
6
6
  let(:parser) { EDN::Parser.new }
7
7
 
8
+ it "can contain comments" do
9
+ edn = ";; This is some sample data\n[1 2 ;; the first two values\n3]"
10
+ parser.should parse(edn)
11
+ parser.parse(edn).should ==
12
+ {:vector=>[{:integer=>"1", :precision=>nil},
13
+ {:integer=>"2", :precision=>nil},
14
+ {:integer=>"3", :precision=>nil}]}
15
+ end
16
+
17
+ it "can discard using the discard reader macro" do
18
+ edn = "[1 2 #_3 {:foo #_bar baz}]"
19
+ parser.should parse(edn)
20
+ parser.parse(edn).should ==
21
+ {:vector=>[{:integer=>"1", :precision=>nil},
22
+ {:integer=>"2", :precision=>nil},
23
+ {:map => [{:key=>{:keyword=>{:symbol=>"foo"}}, :value=>{:symbol=>"baz"}}]}]}
24
+ end
25
+
8
26
  context "value" do
9
27
  it "should consume nil" do
10
28
  parser.value.should parse("nil")
11
29
  end
12
30
  end
13
31
 
32
+ context "comment" do
33
+ it "should consume and throw away comments" do
34
+ comment = "; this is a comment"
35
+ parser.comment.should parse(comment)
36
+ parser.comment.parse(comment).should == "; this is a comment"
37
+ end
38
+ end
39
+
14
40
  context "boolean" do
15
41
  it "should consume true" do
16
42
  parser.boolean.should parse("true")
@@ -75,8 +101,8 @@ describe EDN::Parser do
75
101
 
76
102
  context "tag" do
77
103
  it "should consume any tags" do
78
- rant(RantlyHelpers::SYMBOL).each do |symbol|
79
- parser.tag.should parse("##{symbol}")
104
+ rant(RantlyHelpers::TAG).each do |tag|
105
+ parser.tag.should parse(tag)
80
106
  end
81
107
  end
82
108
  end
@@ -35,7 +35,7 @@ describe EDN::Transform do
35
35
 
36
36
  context "symbol" do
37
37
  it "should emit an EDN symbol" do
38
- subject.apply(:symbol => "test").should == EDN::Type::Symbol.new('test')
38
+ subject.apply(:symbol => "test").should == ~'test'
39
39
  end
40
40
  end
41
41
 
@@ -74,10 +74,10 @@ describe EDN::Transform do
74
74
 
75
75
  context "list" do
76
76
  it "should emit a list" do
77
- subject.apply(:list => []).should == EDN::Type::List.new
78
- subject.apply(:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should == EDN::Type::List.new(1, "abc")
77
+ subject.apply(:list => []).should == EDN.list
78
+ subject.apply(:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should == ~[1, "abc"]
79
79
  subject.apply(:list => [{:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]}, {:float => "3.14", :precision => nil}]).should == \
80
- EDN::Type::List.new(EDN::Type::List.new(1, "abc"), 3.14)
80
+ ~[~[1, "abc"], 3.14]
81
81
  end
82
82
 
83
83
  it "should be type-compatible with arrays" do
data/spec/edn_spec.rb CHANGED
@@ -11,8 +11,8 @@ describe EDN do
11
11
  EDN.read('"hello\nworld"').should == "hello\nworld"
12
12
  EDN.read(':hello').should == :hello
13
13
  EDN.read(':hello/world').should == :"hello/world"
14
- EDN.read('hello').should == EDN::Type::Symbol.new('hello')
15
- EDN.read('hello/world').should == EDN::Type::Symbol.new('hello/world')
14
+ EDN.read('hello').should == ~'hello'
15
+ EDN.read('hello/world').should == ~'hello/world'
16
16
  EDN.read('true').should == true
17
17
  EDN.read('false').should == false
18
18
  EDN.read('nil').should == nil
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,10 @@ REPEAT = (ENV["REPEAT"] || 100).to_i
8
8
 
9
9
  RSpec.configure do |c|
10
10
  c.fail_fast = true
11
+ c.filter_run_including :focused => true
12
+ c.alias_example_to :fit, :focused => true
13
+ c.treat_symbols_as_metadata_keys_with_true_values = true
14
+ c.run_all_when_everything_filtered = true
11
15
  end
12
16
 
13
17
  module RantlyHelpers
@@ -42,7 +46,10 @@ module RantlyHelpers
42
46
 
43
47
  FLOAT_WITH_EXP = lambda { |_|
44
48
  # limited range because of Infinity
45
- [float, choose("e", "E", "e+", "E+", "e-", "e+"), range(1, 100)].
49
+ f = float.to_s
50
+ guard f !~ /[Ee]/
51
+
52
+ [f, choose("e", "E", "e+", "E+", "e-", "e+"), range(1, 100)].
46
53
  map(&:to_s).
47
54
  join("")
48
55
  }
@@ -104,8 +111,14 @@ module RantlyHelpers
104
111
  MAP)
105
112
  }
106
113
 
114
+ TAG = lambda { |_|
115
+ tag = call(SYMBOL)
116
+ guard tag =~ /^[A-Za-z]/
117
+ "##{tag}"
118
+ }
119
+
107
120
  TAGGED_VALUE = lambda { |_|
108
- "#" + [call(SYMBOL), call(BASIC_VALUE)].join(" ")
121
+ [call(TAG), call(BASIC_VALUE)].join(" ")
109
122
  }
110
123
 
111
124
  INST = lambda { |_|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-11 00:00:00.000000000 Z
12
+ date: 2012-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet
@@ -117,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
117
117
  version: '0'
118
118
  segments:
119
119
  - 0
120
- hash: -981297228036091023
120
+ hash: -3622317026699243756
121
121
  required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  none: false
123
123
  requirements:
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  version: '0'
127
127
  segments:
128
128
  - 0
129
- hash: -981297228036091023
129
+ hash: -3622317026699243756
130
130
  requirements: []
131
131
  rubyforge_project:
132
132
  rubygems_version: 1.8.23