Class: Typed::CSVSerializer
- Inherits:
-
Serializer
- Object
- Serializer
- Typed::CSVSerializer
- Defined in:
- lib/typed/csv_serializer.rb
Overview
CSV is a flat, row-based format, so nested structs/hashes/arrays cannot be
represented as their own columns. serialize fails with a SerializeError
naming the offending field(s) rather than writing a lossy representation
that deserialize could never parse back; see README's CSVSerializer
section for the caveat.
Constant Summary collapse
- Input =
type_member { {fixed: String} }
- Output =
type_member { {fixed: String} }
Constants inherited from Serializer
Serializer::DeserializeResult, Serializer::Params
Instance Attribute Summary
Attributes inherited from Serializer
Instance Method Summary collapse
- #deserialize(source) ⇒ Object
-
#initialize(schema:) ⇒ CSVSerializer
constructor
A new instance of CSVSerializer.
- #serialize(struct) ⇒ Object
Constructor Details
#initialize(schema:) ⇒ CSVSerializer
Returns a new instance of CSVSerializer.
14 15 16 17 18 19 |
# File 'lib/typed/csv_serializer.rb', line 14 def initialize(schema:) require "csv" super rescue LoadError raise ArgumentError, "csv gem is required for CSV serialization - add it to your Gemfile" end |
Instance Method Details
#deserialize(source) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/typed/csv_serializer.rb', line 22 def deserialize(source) parsed = CSV.parse(source, headers: true) return Failure.new(ParseError.new(format: :csv)) unless parsed.is_a?(CSV::Table) row = parsed.first return Failure.new(ParseError.new(format: :csv)) unless row.is_a?(CSV::Row) creation_params = schema.fields.each_with_object(T.let({}, Params)) do |field, hsh| hsh[field.name] = row[field.name.to_s] end deserialize_from_creation_params(creation_params) rescue CSV::MalformedCSVError Failure.new(ParseError.new(format: :csv)) end |
#serialize(struct) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/typed/csv_serializer.rb', line 39 def serialize(struct) return Failure.new(SerializeError.new("'#{struct.class}' cannot be serialized to target type of '#{schema.target}'.")) if struct.class != schema.target hsh = serialize_from_struct(struct:, should_serialize_values: true) non_scalar_fields = hsh.select { |_key, value| value.is_a?(Hash) || value.is_a?(Array) }.keys unless non_scalar_fields.empty? return Failure.new(SerializeError.new("'#{struct.class}' cannot be serialized to CSV because field(s) #{non_scalar_fields.join(", ")} are not scalar values.")) end csv_string = CSV.generate do |csv| csv << hsh.keys.map(&:to_s) csv << hsh.values end Success.new(csv_string) end |