evva 0.1.4.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.rspec +0 -1
  4. data/.rubocop_todo.yml +10 -10
  5. data/.travis.yml +1 -0
  6. data/Gemfile +9 -8
  7. data/Gemfile.lock +7 -11
  8. data/README.md +12 -2
  9. data/Rakefile +9 -0
  10. data/changelog.md +18 -1
  11. data/evva.gemspec +0 -3
  12. data/lib/evva/{mixpanel_enum.rb → analytics_enum.rb} +2 -1
  13. data/lib/evva/analytics_event.rb +17 -0
  14. data/lib/evva/analytics_property.rb +17 -0
  15. data/lib/evva/android_generator.rb +141 -84
  16. data/lib/evva/config.rb +21 -4
  17. data/lib/evva/google_sheet.rb +69 -44
  18. data/lib/evva/swift_generator.rb +91 -81
  19. data/lib/evva/templates/kotlin/base.kt +7 -0
  20. data/lib/evva/templates/kotlin/destinations.kt +5 -0
  21. data/lib/evva/templates/kotlin/event_enum.kt +5 -0
  22. data/lib/evva/templates/kotlin/events.kt +34 -0
  23. data/lib/evva/templates/kotlin/people_properties.kt +24 -0
  24. data/lib/evva/templates/kotlin/people_properties_enum.kt +5 -0
  25. data/lib/evva/templates/kotlin/special_property_enums.kt +10 -0
  26. data/lib/evva/templates/swift/base.swift +7 -0
  27. data/lib/evva/templates/swift/destinations.swift +5 -0
  28. data/lib/evva/templates/swift/events.swift +65 -0
  29. data/lib/evva/templates/swift/people_properties.swift +49 -0
  30. data/lib/evva/templates/swift/special_property_enums.swift +10 -0
  31. data/lib/evva/version.rb +2 -2
  32. data/lib/evva.rb +16 -6
  33. data/spec/evva_spec.rb +3 -5
  34. data/spec/fixtures/sample_public_enums.csv +3 -0
  35. data/spec/fixtures/sample_public_events.csv +4 -0
  36. data/spec/fixtures/sample_public_people_properties.csv +4 -0
  37. data/spec/fixtures/test.yml +9 -4
  38. data/spec/lib/evva/android_generator_spec.rb +132 -58
  39. data/spec/lib/evva/config_spec.rb +13 -5
  40. data/spec/lib/evva/google_sheet_spec.rb +60 -72
  41. data/spec/lib/evva/swift_generator_spec.rb +153 -40
  42. metadata +23 -39
  43. data/evva_config.yml +0 -10
  44. data/lib/evva/mixpanel_event.rb +0 -13
  45. data/spec/fixtures/sample_public_enums.html +0 -1
  46. data/spec/fixtures/sample_public_info.html +0 -1
  47. data/spec/fixtures/sample_public_people_properties.html +0 -1
  48. data/spec/fixtures/sample_public_sheet.html +0 -1
@@ -1,79 +1,104 @@
1
1
  require 'net/https'
2
- require 'xmlsimple'
2
+ require 'csv'
3
3
 
4
4
  module Evva
5
5
  class GoogleSheet
6
- def initialize(sheet_id)
7
- @sheet_id = sheet_id
6
+ EVENT_NAME = 'Event Name'
7
+ EVENT_PROPERTIES = 'Event Properties'
8
+ EVENT_DESTINATION = 'Event Destination'
9
+
10
+ PROPERTY_NAME = 'Property Name'
11
+ PROPERTY_TYPE = 'Property Type'
12
+ PROPERTY_DESTINATION = 'Property Destination'
13
+
14
+ ENUM_NAME = 'Enum Name'
15
+ ENUM_VALUES = 'Possible Values'
16
+
17
+ def initialize(events_url, people_properties_url, enum_classes_url)
18
+ @events_url = events_url
19
+ @people_properties_url = people_properties_url
20
+ @enum_classes_url = enum_classes_url
8
21
  end
9
22
 
10
23
  def events
11
- event_list = []
12
- iterate_entries(raw_data(@sheet_id, 0)) do |entry|
13
- event_name = entry['eventname'].first
14
- properties = hash_parser(entry['eventproperties'].first)
15
- event_list << Evva::MixpanelEvent.new(event_name, properties)
24
+ @events_csv ||= begin
25
+ Logger.info("Downloading data from Google Sheet at #{@events_url}")
26
+ get_csv(@events_url)
27
+ end
28
+
29
+ @events ||= @events_csv.map do |row|
30
+ event_name = row[EVENT_NAME]
31
+ properties = hash_parser(row[EVENT_PROPERTIES])
32
+ destinations = row[EVENT_DESTINATION]&.split(',')
33
+ Evva::AnalyticsEvent.new(event_name, properties, destinations || [])
16
34
  end
17
- event_list
18
35
  end
19
36
 
20
37
  def people_properties
21
- people_list = []
22
- iterate_entries(raw_data(@sheet_id, 1)) do |entry|
23
- value = entry['propertyname'].first
24
- people_list << value
38
+ @people_properties_csv ||= begin
39
+ Logger.info("Downloading data from Google Sheet at #{@people_properties_url}")
40
+ get_csv(@people_properties_url)
41
+ end
42
+
43
+ @people_properties ||= @people_properties_csv.map do |row|
44
+ property_name = row[PROPERTY_NAME]
45
+ property_type = row[PROPERTY_TYPE]
46
+ destinations = row[PROPERTY_DESTINATION]&.split(',')
47
+ Evva::AnalyticsProperty.new(property_name, property_type, destinations || [])
25
48
  end
26
- people_list
27
49
  end
28
50
 
29
51
  def enum_classes
30
- enum_list = []
31
- iterate_entries(raw_data(@sheet_id, 2)) do |entry|
32
- enum_name = entry['enumname'].first
33
- values = entry['possiblevalues'].first.split(',')
34
- enum_list << Evva::MixpanelEnum.new(enum_name, values)
52
+ @enum_classes_csv ||= begin
53
+ Logger.info("Downloading data from Google Sheet at #{@enum_classes_url}")
54
+ get_csv(@enum_classes_url)
55
+ end
56
+
57
+ @enum_classes ||= @enum_classes_csv.map do |row|
58
+ enum_name = row[ENUM_NAME]
59
+ values = row[ENUM_VALUES].split(',')
60
+ Evva::AnalyticsEnum.new(enum_name, values)
35
61
  end
36
- enum_list
62
+ end
63
+
64
+ def destinations
65
+ @destinations ||= events.map(&:destinations).flatten.uniq
37
66
  end
38
67
 
39
68
  private
40
69
 
41
- def iterate_entries(data)
42
- Logger.info('Downloading dictionary from Google Sheet...')
43
- non_language_columns = %w[id updated category title content link]
44
- data['entry'].each do |entry|
45
- filtered_entry = entry.reject { |c| non_language_columns.include?(c) }
46
- yield(filtered_entry)
70
+ def get_csv(url)
71
+ data = get(url)
72
+
73
+ begin
74
+ CSV.parse(data, headers: true)
75
+ rescue StandardError => e
76
+ raise "Cannot parse. Expected CSV at #{url}: #{e}"
47
77
  end
48
78
  end
49
79
 
50
- def xml_data(uri, headers = nil)
51
- uri = URI.parse(uri)
80
+ def get(url, max_redirects = 1)
81
+ raise "Too may redirects" if max_redirects == -1
82
+
83
+ uri = URI(url)
84
+
52
85
  http = Net::HTTP.new(uri.host, uri.port)
53
86
  http.use_ssl = true
54
87
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
- data = http.get(uri.path, headers)
56
- unless data.code.to_i == 200
57
- raise "Cannot access sheet at #{uri} - HTTP #{data.code}"
58
- end
59
88
 
60
- begin
61
- XmlSimple.xml_in(data.body, 'KeyAttr' => 'name')
62
- rescue
63
- raise "Cannot parse. Expected XML at #{uri}"
64
- end
65
- end
89
+ request = Net::HTTP::Get.new(uri.request_uri)
90
+ response = http.request(request)
91
+
92
+ return get(response['location'], max_redirects - 1) if response.is_a? Net::HTTPRedirection
93
+
94
+ raise "Http Error #{response.body}" if response.code.to_i >= 400
66
95
 
67
- def raw_data(sheet_id, sheet_number)
68
- Logger.info('Downloading Google Sheet...')
69
- sheet = xml_data("https://spreadsheets.google.com/feeds/worksheets/#{sheet_id}/public/full")
70
- url = sheet['entry'][sheet_number]['link'][0]['href']
71
- xml_data(url)
96
+ response.body
72
97
  end
73
98
 
74
99
  def hash_parser(property_array)
75
100
  h = {}
76
- unless property_array.empty?
101
+ unless property_array.nil? || property_array.empty?
77
102
  property_array.split(',').each do |prop|
78
103
  split_prop = prop.split(':')
79
104
  prop_name = split_prop[0].to_sym
@@ -1,121 +1,132 @@
1
+ require 'erb'
2
+
1
3
  module Evva
2
4
  class SwiftGenerator
3
- EXTENSION_HEADER =
4
- "\nimport Foundation\n\n"\
5
- "extension Analytics {\n\n".freeze
5
+ BASE_TEMPLATE = File.expand_path("./templates/swift/base.swift", __dir__)
6
+ EVENTS_TEMPLATE = File.expand_path("./templates/swift/events.swift", __dir__)
7
+ PEOPLE_PROPERTIES_TEMPLATE = File.expand_path("./templates/swift/people_properties.swift", __dir__)
8
+ SPECIAL_PROPERTY_ENUMS_TEMPLATE = File.expand_path("./templates/swift/special_property_enums.swift", __dir__)
9
+ DESTINATIONS_TEMPLATE = File.expand_path("./templates/swift/destinations.swift", __dir__)
6
10
 
7
- EXTENSION_FOOTER =
8
- "\n\n}\n"
11
+ TAB_SIZE = " " # \t -> 4 spaces
9
12
 
10
- NATIVE_TYPES = %w[Int String Double Float Bool].freeze
13
+ NATIVE_TYPES = %w[Int String Double Float Bool Date].freeze
11
14
 
12
- def events(bundle, file_name)
15
+ def events(bundle, _file_name, _enums_file_name, _destinations_file_name)
13
16
  header_footer_wrapper do
14
- """\tenum Event {
15
- #{bundle.map { |e| event_case(e) }.join("\n")}
16
-
17
- \t\tvar data: EventData {
18
- \t\t\tswitch self {
19
- #{bundle.map { |e| event_data(e) }.join("\n\n")}
20
- \t\t\t}
21
- \t\t}
22
- \t}"""
17
+ events = bundle.map do |event|
18
+ properties = event.properties.map { |k, v|
19
+ type = native_type(v)
20
+
21
+ value_fetcher = k.to_s
22
+
23
+ if is_special_property?(type)
24
+ if type.end_with?('?')
25
+ # optional value, we need ? to access a parameter
26
+ value_fetcher += "?"
27
+ end
28
+ value_fetcher += ".rawValue"
29
+ end
30
+
31
+ {
32
+ name: k.to_s,
33
+ type: type,
34
+ value: value_fetcher,
35
+ }
36
+ }
37
+
38
+ {
39
+ case_name: camelize(event.event_name),
40
+ event_name: event.event_name,
41
+ properties: properties,
42
+ destinations: event.destinations.map { |p| camelize(p) },
43
+ }
44
+ end
45
+
46
+ template_from(EVENTS_TEMPLATE).result(binding)
23
47
  end
24
48
  end
25
49
 
26
- def event_case(event_data)
27
- function_name = camelize(event_data.event_name)
28
- if event_data.properties.empty?
29
- "\t\tcase #{function_name}"
30
- else
31
- trimmed_properties = event_data.properties.map { |k, v| k.to_s + ': ' + native_type(v) }.join(", ")
32
- "\t\tcase #{function_name}(#{trimmed_properties})"
33
- end
50
+ def event_enum
51
+ # empty
34
52
  end
35
53
 
36
- def event_data(event_data)
37
- function_name = camelize(event_data.event_name)
38
- if event_data.properties.empty?
39
- function_body = "\t\t\tcase .#{function_name}:\n" \
40
- "\t\t\t\treturn EventData(name: \"#{event_data.event_name}\")"
41
- else
42
- function_header = prepend_let(event_data.properties)
43
- function_arguments = dictionary_pairs(event_data.properties)
44
- function_body = "\t\t\tcase .#{function_name}(#{function_header}):\n"\
45
- "\t\t\t\treturn EventData(name: \"#{event_data.event_name}\", properties: [\n"\
46
- "\t\t\t\t\t#{function_arguments.join(",\n\t\t\t\t\t")} ]\n"\
47
- "\t\t\t\t)"
54
+ def people_properties(people_bundle, _file_name, _enums_file_name, _destinations_file_name)
55
+ header_footer_wrapper do
56
+ properties = people_bundle.map do |p|
57
+ type = native_type(p.type)
58
+ {
59
+ case_name: camelize(p.property_name),
60
+ property_name: p.property_name,
61
+ type: type,
62
+ is_special_property: is_special_property?(type),
63
+ destinations: p.destinations.map { |p| camelize(p) },
64
+ }
65
+ end
66
+
67
+ template_from(PEOPLE_PROPERTIES_TEMPLATE).result(binding)
48
68
  end
49
- function_body
50
69
  end
51
70
 
52
- def event_enum(enum, file_name)
71
+ def people_properties_enum
53
72
  # empty
54
73
  end
55
74
 
56
- def people_properties(people_bundle, file_name)
75
+ def special_property_enums(enums_bundle)
57
76
  header_footer_wrapper do
58
- props = "\tenum Property: String {\n"
59
- people_bundle.each do |prop|
60
- props << "\t\tcase #{camelize(prop)} = \"#{prop}\"\n"
77
+ enums = enums_bundle.map do |enum|
78
+ values = enum.values.map do |value|
79
+ {
80
+ case_name: camelize(value),
81
+ value: value
82
+ }
83
+ end
84
+
85
+ {
86
+ name: enum.enum_name,
87
+ values: values
88
+ }
61
89
  end
62
- props << "\t}"
90
+
91
+ template_from(SPECIAL_PROPERTY_ENUMS_TEMPLATE).result(binding)
63
92
  end
64
93
  end
65
94
 
66
- def special_property_enums(enums)
95
+ def destinations(destinations_bundle, _file_name)
67
96
  header_footer_wrapper do
68
- enums.map do |enum|
69
- body = "\tenum #{enum.enum_name}: String {\n"
70
- enum.values.each do |value|
71
- body << "\t\tcase #{camelize(value)} = \"#{value}\"\n"
72
- end
73
- body << "\t}"
74
- end.join("\n\n")
97
+ destinations = destinations_bundle.map { |p| camelize(p) }
98
+
99
+ template_from(DESTINATIONS_TEMPLATE).result(binding)
75
100
  end
76
101
  end
77
102
 
78
103
  private
79
104
 
80
105
  def header_footer_wrapper
81
- """// This file was automatically generated by evva: https://github.com/hole19/evva
82
-
83
- import Foundation
106
+ content = yield
107
+ .gsub(/^/, "\t").gsub(/^\t+$/, "") # add tabs, unless it's an empty line
108
+ .chop # trim trailing newlines created by sublime
84
109
 
85
- extension Analytics {
86
-
87
- #{yield.gsub("\t", " ")}
88
- }
89
- """
110
+ template_from(BASE_TEMPLATE).result(binding).gsub("\t", TAB_SIZE)
90
111
  end
91
112
 
92
- def dictionary_pairs(props)
93
- props.map do |name, type|
94
- pair = "\"#{name}\": #{name}"
95
- if is_raw_representable_property?(type)
96
- if is_optional_property?(type)
97
- pair += "?"
98
- end
99
- pair += ".rawValue"
100
- end
101
- pair += " as Any"
102
- end
103
- end
113
+ def template_from(path)
114
+ file = File.read(path)
104
115
 
105
- def is_raw_representable_property?(type)
106
- !NATIVE_TYPES.include?(native_type(type).chomp('?'))
107
- end
108
-
109
- def is_optional_property?(type)
110
- type.end_with?('?')
116
+ # - 2nd argument (nil) changes nothing
117
+ # - 3rd argument activates trim mode using "-" so that you can decide to
118
+ # not include a line (useful on loops and if statements)
119
+ ERB.new(file, nil, '-')
111
120
  end
112
121
 
113
122
  def native_type(type)
114
- type.gsub('Boolean','Bool').gsub('Long', 'Int')
123
+ type
124
+ .gsub('Boolean','Bool')
125
+ .gsub('Long', 'Int')
115
126
  end
116
127
 
117
- def prepend_let(props)
118
- props.map { |k, v| "let #{k}" }.join(', ')
128
+ def is_special_property?(type)
129
+ !NATIVE_TYPES.include?(type.chomp('?'))
119
130
  end
120
131
 
121
132
  def camelize(term)
@@ -125,6 +136,5 @@ extension Analytics {
125
136
  string.gsub!("/".freeze, "::".freeze)
126
137
  string
127
138
  end
128
-
129
139
  end
130
140
  end
@@ -0,0 +1,7 @@
1
+ package <%= package_name %>
2
+
3
+ /**
4
+ * This file was automatically generated by evva: https://github.com/hole19/evva
5
+ */
6
+
7
+ <%= content %>
@@ -0,0 +1,5 @@
1
+ enum class <%= class_name %> {
2
+ <%- destinations.each_with_index do |destination, index| -%>
3
+ <%= destination %><%= index == destinations.count - 1 ? ";" : "," %>
4
+ <%- end -%>
5
+ }
@@ -0,0 +1,5 @@
1
+ enum class <%= class_name %>(val key: String) {
2
+ <%- events.each_with_index do |event, index| -%>
3
+ <%= event[:name] %>("<%= event[:value] %>")<%= index == events.count - 1 ? ";" : "," %>
4
+ <%- end -%>
5
+ }
@@ -0,0 +1,34 @@
1
+ sealed class <%= class_name %>(event: <%= enums_class_name %>) {
2
+ val name = event.key
3
+
4
+ open val properties: Map<String, Any?>? = null
5
+ open val destinations: Array<<%= destinations_class_name %>> = []
6
+
7
+ <%- events.each_with_index do |e, index| -%>
8
+ <%- if e[:is_object] -%>
9
+ object <%= e[:class_name] %> : <%= class_name %>(<%= enums_class_name %>.<%= e[:event_name] %>)
10
+ <%- else -%>
11
+ data class <%= e[:class_name] %><% if e[:properties].count > 0 %>(
12
+ <%= e[:properties].map { |p| "val #{p[:param_name]}: #{p[:type]}" }.join(", ") %>
13
+ )<% end %> : <%= class_name %>(<%= enums_class_name %>.<%= e[:event_name] %>) {
14
+ <%- if e[:properties].count > 0 -%>
15
+ override val properties = mapOf(
16
+ <%- e[:properties].each_with_index do |p, index| -%>
17
+ "<%= p[:name] %>" to <%= p[:value_fetcher] %><% if index < e[:properties].count - 1 %>,<% end %>
18
+ <%- end -%>
19
+ )
20
+ <%- end -%>
21
+ <%- if e[:destinations].count > 0 -%>
22
+ override val destinations = [
23
+ <%- e[:destinations].each_with_index do |d, index| -%>
24
+ <%= destinations_class_name %>.<%= d %><% if index < e[:destinations].count - 1 %>,<% end %>
25
+ <%- end -%>
26
+ ]
27
+ <%- end -%>
28
+ }
29
+ <%- end -%>
30
+ <%- unless index == events.count - 1 -%>
31
+
32
+ <%- end -%>
33
+ <%- end -%>
34
+ }
@@ -0,0 +1,24 @@
1
+ sealed class <%= class_name %>(property: <%= enums_class_name %>) {
2
+ val name = property.key
3
+
4
+ open val value: Any = ""
5
+ open val destinations: Array<<%= destinations_class_name %>> = []
6
+
7
+ <%- properties.each_with_index do |property, index| -%>
8
+ data class <%= property[:class_name] %>(
9
+ val value: <%= property[:type] %>
10
+ ) : <%= class_name %>(<%= enums_class_name %>.<%= property[:property_name] %>) {
11
+ override val value = value<% if property[:is_special_property] %>.key<% end %>
12
+ <%- if property[:destinations].count > 0 -%>
13
+ override val destinations = [
14
+ <%- property[:destinations].each_with_index do |d, index| -%>
15
+ <%= destinations_class_name %>.<%= d %><% if index < property[:destinations].count - 1 %>,<% end %>
16
+ <%- end -%>
17
+ ]
18
+ <%- end -%>
19
+ }
20
+ <%- unless index == properties.count - 1 -%>
21
+
22
+ <%- end -%>
23
+ <%- end -%>
24
+ }
@@ -0,0 +1,5 @@
1
+ enum class <%= class_name %>(val key: String) {
2
+ <%- properties.each_with_index do |property, index| -%>
3
+ <%= property[:name] %>("<%= property[:value] %>")<%= index == properties.count - 1 ? ";" : "," %>
4
+ <%- end -%>
5
+ }
@@ -0,0 +1,10 @@
1
+ <%- enums.each_with_index do |enum, index| -%>
2
+ enum class <%= enum[:class_name] %>(val key: String) {
3
+ <%- enum[:values].each_with_index do |v, index| -%>
4
+ <%= v[:name] %>("<%= v[:value] %>")<%= index == enum[:values].count - 1 ? ";" : "," %>
5
+ <%- end -%>
6
+ }
7
+ <%- unless index == enums.count - 1 -%>
8
+
9
+ <%- end -%>
10
+ <%- end -%>
@@ -0,0 +1,7 @@
1
+ // This file was automatically generated by evva: https://github.com/hole19/evva
2
+
3
+ import Foundation
4
+
5
+ extension Analytics {
6
+ <%= content %>
7
+ }
@@ -0,0 +1,5 @@
1
+ enum Destination {
2
+ <%- destinations.each do |d| -%>
3
+ case <%= d %>
4
+ <%- end -%>
5
+ }
@@ -0,0 +1,65 @@
1
+ struct EventData {
2
+ let name: String
3
+ var properties: [String: Any]?
4
+ let destinations: [Destination]
5
+
6
+ init(name: String, properties: [String: Any]?, destinations: [Destination]) {
7
+ self.name = name
8
+ self.properties = properties
9
+ self.destinations = destinations
10
+ }
11
+
12
+ init(name: EventName, properties: [String: Any]?, destinations: [Destination]) {
13
+ self.init(name: name.rawValue, properties: properties, destinations: destinations)
14
+ }
15
+ }
16
+
17
+ enum EventName: String {
18
+ <%- events.each do |e| -%>
19
+ case <%= e[:case_name] %> = "<%= e[:event_name] %>"
20
+ <%- end -%>
21
+ }
22
+
23
+ enum Event {
24
+ <%- events.each do |e| -%>
25
+ <%- if e[:properties].count == 0 -%>
26
+ case <%= e[:case_name] %>
27
+ <%- else -%>
28
+ case <%= e[:case_name] %>(<%= e[:properties].map { |p| "#{p[:name]}: #{p[:type]}" }.join(", ") %>)
29
+ <%- end -%>
30
+ <%- end -%>
31
+
32
+ var data: EventData {
33
+ switch self {
34
+ <%- events.each_with_index do |e, index| -%>
35
+ <%- if e[:properties].count == 0 -%>
36
+ case .<%= e[:case_name] %>:
37
+ <%- else -%>
38
+ case let .<%= e[:case_name] %>(<%= e[:properties].map { |p| p[:name] }.join(", ") %>):
39
+ <%- end -%>
40
+ return EventData(name: .<%= e[:case_name] %>,
41
+ <%- if e[:properties].count == 0 -%>
42
+ properties: nil,
43
+ <%- else -%>
44
+ properties: [
45
+ <%- e[:properties].each do |p| -%>
46
+ "<%= p[:name] %>": <%= p[:value] %> as Any,
47
+ <%- end -%>
48
+ ],
49
+ <%- end -%>
50
+ <%- if e[:destinations].count == 0 -%>
51
+ destinations: [])
52
+ <%- else -%>
53
+ destinations: [
54
+ <%- e[:destinations].each do |d| -%>
55
+ .<%= d %>,
56
+ <%- end -%>
57
+ ])
58
+ <%- end -%>
59
+ <%- unless index == events.count - 1 -%>
60
+
61
+ <%- end -%>
62
+ <%- end -%>
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,49 @@
1
+ struct PropertyData {
2
+ let name: String
3
+ let value: Any
4
+ let destinations: [Destination]
5
+
6
+ init(name: String, value: Any, destinations: [Destination]) {
7
+ self.name = name
8
+ self.value = value
9
+ self.destinations = destinations
10
+ }
11
+
12
+ init(name: PropertyName, value: Any, destinations: [Destination]) {
13
+ self.init(name: name.rawValue, value: value, destinations: destinations)
14
+ }
15
+ }
16
+
17
+ enum PropertyName: String {
18
+ <%- properties.each do |p| -%>
19
+ case <%= p[:case_name] %> = "<%= p[:property_name ] %>"
20
+ <%- end -%>
21
+ }
22
+
23
+ enum Property {
24
+ <%- properties.each do |p| -%>
25
+ case <%= p[:case_name] %>(<%= p[:type] %>)
26
+ <%- end -%>
27
+
28
+ var data: PropertyData {
29
+ switch self {
30
+ <%- properties.each_with_index do |p, index| -%>
31
+ case let .<%= p[:case_name] %>(value):
32
+ return PropertyData(name: .<%= p[:case_name] %>,
33
+ value: value<% if p[:is_special_property] %>.rawValue<% end %>,
34
+ <%- if p[:destinations].count == 0 -%>
35
+ destinations: [])
36
+ <%- else -%>
37
+ destinations: [
38
+ <%- p[:destinations].each do |d| -%>
39
+ .<%= d %>,
40
+ <%- end -%>
41
+ ])
42
+ <%- end -%>
43
+ <%- unless index == properties.count - 1 -%>
44
+
45
+ <%- end -%>
46
+ <%- end -%>
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,10 @@
1
+ <%- enums.each_with_index do |enum, index| -%>
2
+ enum <%= enum[:name] %>: String {
3
+ <%- enum[:values].each do |v| -%>
4
+ case <%= v[:case_name] %> = "<%= v[:value ] %>"
5
+ <%- end -%>
6
+ }
7
+ <%- unless index == enums.count - 1 -%>
8
+
9
+ <%- end -%>
10
+ <%- end -%>
data/lib/evva/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Evva
2
- VERSION = '0.1.4.3'.freeze
3
- VERSION_UPDATED_AT = '2018-10-12'.freeze
2
+ VERSION = '0.4.0'.freeze
3
+ VERSION_UPDATED_AT = '2021-12-21'.freeze
4
4
  end