module Analytics module Serializer class Swift < Base class Event def initialize(src) @src = src end def save(path) @file_name = 'AnalyticsEvent.swift' output_path = File.join(path, @file_name) File.write(output_path, render) end private def render ERB.new(template, nil, '-').result(binding) end def template <<~TEMPLATE <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %> import Foundation extension Analytics { struct Event { let name: String let properties: [String: Any] private init(name: String, properties: [String: Any] = [:]) { self.name = name self.properties = properties } } } // MARK: - Events extension Analytics.Event { <% @src["events"].each do |event| -%> /// <%= event["description"] -%> <% if event["properties"].nil? %> static var <%= event["name"].camel_case %>: Analytics.Event { return .init(name: "<%= event["name"] %>") } <% else %> <% event["properties"].each do |property| -%> /// - Parameter <%= property["name"] %>: <%= property["description"] %> <% end -%> static func <%= event['name'].camel_case %>(<%= format_method_params(event)-%>) -> Analytics.Event { return .init(name: "<%= event["name"] %>", properties: <%= format_init_properties(event["properties"]) %>) } <% end -%> <% end %> } // MARK: - Event Property Enums extension Analytics.Event { <% Interactor::Event.all_enum_properties(@src['events']).each do |event| -%> <% event['properties'].each do |property| -%> /// <%= property['description'] %> enum <%= event['name'].pascal_case + property['name'].pascal_case -%>: String { <% property["values"].each do |value| -%> case <%= value.camel_case -%> = "<%= value %>" <% end -%> } <% end -%> <% end -%> } TEMPLATE end ## Helper methods called from the ERB template # Formats the parameters in Swift method. def format_method_params(event) result = event['properties'].map do |property| "#{property['name'].camel_case}: #{format_property_type_from_event(property, event)}" end return result.join(', ') end # Maps the property type to Swift type. def format_property_type_from_event(property, event) # if it doesn't have values, it's not an enum, # and if it does, we'll return capitalized property name, # because an enum with the same name will be generated as well if property['values'].nil? case property['type'] when 'text' 'String' when 'number' 'Int' when 'decimal' 'Double' else 'unknown-type' end else event['name'].pascal_case + property['name'].pascal_case end end # Formats the properties passed to Event's init. def format_init_properties(properties) result = properties.map do |property| "\"#{property['name']}\": #{property['name'].camel_case}#{'.rawValue' unless property['values'].nil?}" end results = "[#{result.join(', ')}]" end end end end end