Class: Eddy::Build::SegmentBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/eddy/build/segment_builder.rb

Overview

Generate Ruby code from JSON/YAML EDI definitions.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(folder: nil) ⇒ void

Parameters:

  • folder (String) (defaults to: nil)

    (nil)



19
20
21
# File 'lib/eddy/build/segment_builder.rb', line 19

def initialize(folder: nil)
  self.folder = folder
end

Instance Attribute Details

#duplicate_elementsHash{String => Integer}

A hash of element names that appear more than once in the segment.

Returns:

  • (Hash{String => Integer})


15
16
17
# File 'lib/eddy/build/segment_builder.rb', line 15

def duplicate_elements
  @duplicate_elements
end

#folderString

Returns (nil).

Returns:

  • (String)

    (nil)



12
13
14
# File 'lib/eddy/build/segment_builder.rb', line 12

def folder
  @folder
end

#summaryEddy::Summary::Segment



10
11
12
# File 'lib/eddy/build/segment_builder.rb', line 10

def summary
  @summary
end

Class Method Details

.element_accessor_v1(el, header: :summary) ⇒ String

Parameters:

  • el (Eddy::Summary::Element)
  • header (Symbol) (defaults to: :summary)

    (see Eddy::Summary::Element#doc_comment)

Returns:

  • (String)


127
128
129
130
131
132
133
134
135
136
137
# File 'lib/eddy/build/segment_builder.rb', line 127

def self.element_accessor_v1(el, header: :summary)
  return <<~RB.strip
    #{el.doc_comment(header: header).gsub(/^/, '# ').gsub(/([[:blank:]]+)$/, '')}
    #
    # @param arg [#{el.yard_type}]
    # @return [void]
    def #{el.ref.upcase}=(arg)
      @#{el.ref.downcase}.value = arg
    end
  RB
end

.element_accessor_v2(el, dupes, header: :ref) ⇒ String

Parameters:

Returns:

  • (String)


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/eddy/build/segment_builder.rb', line 143

def self.element_accessor_v2(el, dupes, header: :ref)
  if dupes.key?(el.name)
    normal_name = el.normalized_name + dupes[el.name].to_s
    dupes[el.name] += 1
  else
    normal_name = el.normalized_name
  end
  return <<~RB.strip
    #{el.doc_comment(header: header).gsub(/^/, '# ').gsub(/([[:blank:]]+)$/, '')}
    #
    # @param arg [#{el.yard_type}]
    # @return [void]
    def #{el.ref.upcase}=(arg)
      @#{el.ref.downcase}.value = arg
    end
    alias #{normal_name}= #{el.ref.upcase}=
  RB
end

.from_file(path, **kwargs) ⇒ Eddy::Build::SegmentBuilder

Parameters:

  • path (String)

    Path to a JSON or YAML file containing a valid Segment definition.

  • folder (String)

    (nil)

Returns:

Raises:



26
27
28
29
30
31
32
# File 'lib/eddy/build/segment_builder.rb', line 26

def self.from_file(path, **kwargs)
  raise Eddy::Errors::Error, "Invalid segment definition" unless Eddy::Summary.valid_segment_data?(path)
  data = Eddy::Util.read_json_or_yaml(path)
  sb = Eddy::Build::SegmentBuilder.new(**kwargs)
  sb.summary = Eddy::Summary::Segment.create(data)
  return sb
end

.from_summary(summary, **kwargs) ⇒ Eddy::Build::SegmentBuilder

Parameters:

Returns:



37
38
39
40
41
# File 'lib/eddy/build/segment_builder.rb', line 37

def self.from_summary(summary, **kwargs)
  sb = new(**kwargs)
  sb.summary = summary
  return sb
end

Instance Method Details

#accessorsString

Returns:

  • (String)


116
117
118
119
120
121
122
# File 'lib/eddy/build/segment_builder.rb', line 116

def accessors()
  self.find_duplicate_elements()
  defs = self.summary.elements.map do |el|
    Eddy::Build::SegmentBuilder.element_accessor_v2(el, self.duplicate_elements)
  end
  return defs.join("\n\n")
end

#build(build_elements: false) ⇒ String

Generated the Segment and return the name of the file where it was written.

Parameters:

  • build_elements (Boolean) (defaults to: false)

    (false)

Returns:

  • (String)


47
48
49
50
51
52
53
54
55
# File 'lib/eddy/build/segment_builder.rb', line 47

def build(build_elements: false)
  Eddy::Build.make_folders()
  if build_elements
    Eddy::Build::Elements.generate_elements(self.summary.elements)
  end
  path = self.folder || File.join(Eddy.config.build_dir, "segments")
  result = self.ginny_class.generate(path)
  return result
end

#constructorString

Returns:

  • (String)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/eddy/build/segment_builder.rb', line 80

def constructor()
  return Ginny::Func.create({
    name: "initialize",
    params: [{ name: "store", type: "Eddy::Data::Store" }],
    body: <<~RB,
      @id = "#{summary.id}"
      @name = "#{summary.name}"
      #{self.declarations()}



      #{self.super_call()}
    RB
  }).render()
end

#declarationsString

Returns:

  • (String)


97
98
99
100
101
102
103
104
# File 'lib/eddy/build/segment_builder.rb', line 97

def declarations()
  decs = ""
  self.summary.elements.each do |el|
    req = el.req.nil? ? "nil" : '"' + el.req + '"'
    decs << %(@#{el.ref.to_s.downcase} = Eddy::Elements::#{Eddy::Util.normalize_id(el.id)}.new(ref: "#{el.ref.to_s.upcase}", req: #{req})\n)
  end
  return decs
end

#find_duplicate_elementsvoid

This method returns an undefined value.



163
164
165
166
167
168
169
170
# File 'lib/eddy/build/segment_builder.rb', line 163

def find_duplicate_elements()
  names = self.summary.elements.map(&:name)
  s = Set.new()
  dupes = names.reject { |e| s.add?(e) }.uniq
  self.duplicate_elements = {}
  dupes.each { |d| self.duplicate_elements[d] = 1 }
  return nil
end

#ginny_classGinny::Class

Returns:

  • (Ginny::Class)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/eddy/build/segment_builder.rb', line 63

def ginny_class()
  return Ginny::Class.create({
    classify_name: false,
    modules: ["Eddy", "Segments"],
    parent: "Eddy::Models::Segment",
    name: summary.id,
    description: summary.doc_comment(header: true),
    body: <<~STR,

      #{self.constructor()}

      #{self.accessors()}
    STR
  })
end

#renderString

Returns:

  • (String)


58
59
60
# File 'lib/eddy/build/segment_builder.rb', line 58

def render()
  return self.ginny_class.render()
end

#super_callString

Returns:

  • (String)


107
108
109
110
111
112
113
# File 'lib/eddy/build/segment_builder.rb', line 107

def super_call()
  super_call = "super(\n"
  super_call << "  store,\n"
  self.summary.elements.each { |el| super_call << "  @#{el.ref.to_s.downcase},\n" }
  super_call << ")"
  return super_call
end