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 +4 -4
- data/lib/edn.rb +14 -5
- data/lib/edn/core_ext.rb +8 -0
- data/lib/edn/parser.rb +39 -3
- data/lib/edn/transform.rb +1 -1
- data/lib/edn/version.rb +1 -1
- data/spec/edn/parser_spec.rb +28 -2
- data/spec/edn/transform_spec.rb +4 -4
- data/spec/edn_spec.rb +2 -2
- data/spec/spec_helper.rb +15 -2
- metadata +4 -4
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/
|
130
|
-
[README]: https://github.com/
|
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
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
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.
|
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
|
171
|
+
(discard | comment | match['\s,']).repeat(1)
|
136
172
|
}
|
137
173
|
|
138
174
|
rule(:space?) { space.maybe }
|
data/lib/edn/transform.rb
CHANGED
data/lib/edn/version.rb
CHANGED
data/spec/edn/parser_spec.rb
CHANGED
@@ -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::
|
79
|
-
parser.tag.should parse(
|
104
|
+
rant(RantlyHelpers::TAG).each do |tag|
|
105
|
+
parser.tag.should parse(tag)
|
80
106
|
end
|
81
107
|
end
|
82
108
|
end
|
data/spec/edn/transform_spec.rb
CHANGED
@@ -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 ==
|
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
|
78
|
-
subject.apply(:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should ==
|
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
|
-
|
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 ==
|
15
|
-
EDN.read('hello/world').should ==
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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: -
|
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: -
|
129
|
+
hash: -3622317026699243756
|
130
130
|
requirements: []
|
131
131
|
rubyforge_project:
|
132
132
|
rubygems_version: 1.8.23
|