-
Notifications
You must be signed in to change notification settings - Fork 0
/
008.rb
51 lines (41 loc) · 1.17 KB
/
008.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'parslet'
end
txt1 = 'v=BIMI1; l=uri'
pp txt1
class TxtParser < Parslet::Parser
root :record
rule :record do
(
bimi_data.as(:bimi_data) >>
location_data.as(:location_data)
).as(:record)
end
rule :bimi_data do
str('v') >> item_separator >> match['[:alnum:]'].repeat.as(:v) >> field_separator
end
rule :location_data do
str('l') >> item_separator >> match['[:alnum:]'].repeat.as(:l) >> field_separator
end
# helpers
rule(:space?) { match[' \t'].maybe }
rule(:item_separator) { space? >> str('=') >> space? }
rule(:field_separator) { space? >> str(';').maybe >> space? }
end
parsed1 = TxtParser.new.parse(txt1)
pp parsed1
pp parsed1.dig(:record, :bimi_data, :v).class
require 'uri'
class TxtTransform < Parslet::Transform
rule(v: simple(:v)) { v.to_s }
rule(l: simple(:l)) { URI.parse("https://example.com") }
rule(record: subtree(:record)) do
Struct.new("Record", :bimi_data, :location_data, keyword_init: true).new(record)
end
end
transformed1 = TxtTransform.new.apply(parsed1)
pp transformed1
pp transformed1.bimi_data
pp transformed1.location_data