Skip to content

Commit

Permalink
Phlex::CSV
Browse files Browse the repository at this point in the history
Co-Authored-By: Will Cosgrove <[email protected]>
  • Loading branch information
joeldrapper and willcosgrove committed Feb 9, 2024
1 parent 81d0a1b commit b9bf9fd
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/phlex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ module Phlex
autoload :Unbuffered, "phlex/unbuffered"
autoload :ConcurrentMap, "phlex/concurrent_map"
autoload :BlackHole, "phlex/black_hole"
autoload :CSV, "phlex/csv"
autoload :Callable, "phlex/callable"

# Included in all Phlex exceptions allowing you to match any Phlex error.
# @example Rescue any Phlex error:
Expand Down
75 changes: 75 additions & 0 deletions lib/phlex/csv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

require "csv"

class Phlex::CSV
include Phlex::Callable

def initialize(collection)
@_collection = collection
@_headers = []
@_current_row = []
@_current_column_index = 0
@_view_context = nil
@_first = true
end

def call(buffer = +"", view_context: nil)
@_view_context = view_context

@_collection.each do |record|
collection_yielder(record) do |*args, **kwargs|
template(*args, **kwargs)

if @_first && render_headers?
buffer << ::CSV.generate_line(@_headers)
end

buffer << ::CSV.generate_line(@_current_row)
@_current_column_index = 0
@_current_row.clear
end

@_first = false
end

buffer
end

def filename
nil
end

private

def column(header = nil, value)
if @_first
@_headers << header
else
raise unless header == @_headers[@_current_column_index]
end

@_current_row << value
@_current_column_index += 1
end

def collection_yielder(record)
yield(record)
end

def template(...)
nil
end

def render_headers?
true
end

def helpers
@_view_context
end

def render(renderable)
renderable.call(view_context: @_view_context)
end
end
30 changes: 30 additions & 0 deletions test/phlex/csv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Report < Phlex::CSV
def template(user)
user => { id:, name:, email: }

column("id", id)
column("name", name)
column("email", email)
end
end

User = Data.define(:id, :name, :email)

it "works" do
users = [
User.new(
id: 1,
name: "John Doe",
email: "[email protected]"
),
User.new(
id: 2,
name: "Jane Doe",
email: "[email protected]"
)
]

puts Report.new(
users
).call
end

0 comments on commit b9bf9fd

Please sign in to comment.