Module: SoberSwag::Reporting::Input::Converting

Defined in:
lib/sober_swag/reporting/input/converting.rb,
lib/sober_swag/reporting/input/converting/bool.rb,
lib/sober_swag/reporting/input/converting/date.rb,
lib/sober_swag/reporting/input/converting/decimal.rb,
lib/sober_swag/reporting/input/converting/integer.rb,
lib/sober_swag/reporting/input/converting/date_time.rb

Overview

Namespace for things that can do conversion. These are really just compound types that kinda look nice.

Constant Summary collapse

Bool =

Try to convert a boolean-like value to an actual boolean.

(SoberSwag::Reporting::Input::Bool.new |
 (
   SoberSwag::Reporting::Input::Text
    .new
    .enum(*(%w[y yes true t].flat_map { |x| [x, x.upcase] } + ['1'])) |
    SoberSwag::Reporting::Input::Number.new.enum(1)).mapped { |_| true } |
  (
    SoberSwag::Reporting::Input::Text
      .new
      .enum(*(%w[false no n f].flat_map { |x| [x, x.upcase] } + ['0'])) |
    SoberSwag::Reporting::Input::Number.new.enum(0)
  ).mapped { |_| false }
)
Date =

Convert via a date.

Note: unlike the swagger spec, we first try to convert rfc8601, then try rfc3339.

(
SoberSwag::Reporting::Input::Text
     .new
     .mapped { |str|
  begin
    ::Date.rfc3339(str)
  rescue ArgumentError
    Report::Value.new(['was not an RFC 3339 date string'])
  end
} |
SoberSwag::Reporting::Input::Text
  .new
  .mapped do |str|
  ::Date.iso8601(str)
rescue ArgumentError
  Report::Value.new(['was not an ISO8601 date string'])
end).format('date')
Decimal =

Parse a decimal.

(SoberSwag::Reporting::Input::Number.new.mapped(&:to_d).format(:decimal) |
SoberSwag::Reporting::Input::Text
.new
.format('decimal')
.mapped do |v|
  BigDecimal(v)
rescue ArgumentError
  Report::Value.new(['was not a decimal'])
end).described(<<~MARKDOWN).referenced('SoberSwag.Converting.Decimal')
  Decimal formatted input.
  Will either convert a JSON number to a decimal, or accept a string representation.
  The string representation allows for greater precision.
MARKDOWN
Integer =
(SoberSwag::Reporting::Input.number.format('integer').mapped(&:to_i)) |
(SoberSwag::Reporting::Input.text.format('integer').mapped do |v|
  Integer(v)
rescue ArgumentError
  Report::Value.new(['was not an integer string'])
end).described(<<~MARKDOWN).referenced('SoberSwag.Converting.Integer')
  Integer formatted input.

  With either convert a JSON number to an integer, or accept a string representation of an integer.
MARKDOWN
DateTime =

Convert via a date.

SoberSwag::Reporting::Input::Text
.new
.mapped { |str|
  begin
    ::DateTime.rfc3339(str)
  rescue ArgumentError
    Report::Value.new(['was not an RFC 3339 date-time string'])
  end
}.or(
  SoberSwag::Reporting::Input::Text
    .new
    .mapped do |str|
    ::DateTime.iso8601(str)
  rescue ArgumentError
    Report::Value.new(['was not an ISO8601 date-time string'])
  end
).format('date-time')