NAME
    App::fiatx - Fiat currency exchange rate tool

VERSION
    This document describes version 0.008 of App::fiatx (from Perl
    distribution App-fiatx), released on 2021-05-26.

SYNOPSIS
    See the included script fiatx.

FUNCTIONS
  fiatx
    Usage:

     fiatx(%args) -> [$status_code, $reason, $payload, \%result_meta]

    Currency exchange rate tool.

    This function is not exported.

    Arguments ('*' denotes required arguments):

    *   action => *str* (default: "get_spot_rates")

    *   db_name => *str*

    *   db_password => *str*

    *   db_username => *str*

    *   default_quote_currency => *fiat_or_cryptocurrency*

    *   max_age_cache => *nonnegint* (default: 14400)

        Above this age (in seconds), we retrieve rate from remote source
        again.

    *   query => *str*

    *   sources => *array[str]*

    Returns an enveloped result (an array).

    First element ($status_code) is an integer containing HTTP-like status
    code (200 means OK, 4xx caller error, 5xx function error). Second
    element ($reason) is a string containing error message, or something
    like "OK" if status is 200. Third element ($payload) is the actual
    result, but usually not present when enveloped result is an error
    response ($status_code is not 2xx). Fourth element (%result_meta) is
    called result metadata and is optional, a hash that contains extra
    information, much like how HTTP response headers provide additional
    metadata.

    Return value: (any)

HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/App-fiatx>.

SOURCE
    Source repository is at <https://github.com/perlancar/perl-App-fiatx>.

BUGS
    Please report any bugs or feature requests on the bugtracker website
    <https://github.com/perlancar/perl-App-fiatx/issues>

    When submitting a bug or request, please include a test-file or a patch
    to an existing test-file that illustrates the bug or desired feature.

SEE ALSO
    Finance::Currency::FiatX

                my @rows;
        my $resmeta = {};

        if ($args{per_type}) {
            for (@$rows0) {
                delete $_->{source} unless $source eq ':all';
                push @rows, $_;
            }
            $resmeta->{'table.fields'}        = ['source', 'pair', 'type' , 'rate' , 'note'];
            $resmeta->{'table.field_formats'} = [undef   , undef , undef  , $fnum8 , undef ];
            $resmeta->{'table.field_aligns'}  = ['left'  , 'left', 'right', 'right', 'left'];
            unless ($source eq ':all') {
                shift @{ $resmeta->{'table.fields'} };
                shift @{ $resmeta->{'table.field_formats'} };
                shift @{ $resmeta->{'table.field_aligns'} };
            }
        } else {
            my %sources;
            for my $r (@$rows0) {
                my $src = $r->{source} // '';
                $sources{ $src }++;
            }

            for my $src (sort keys %sources) {
                my %per_pair_rates;
                for my $r (@$rows0) {
                    next unless ($r->{source} // '') eq $src;
                    $per_pair_rates{ $r->{pair} } //= {
                        pair => $r->{pair},
                        mtime => 0,
                    };
                    $per_pair_rates{ $r->{pair} }{source} = $src
                        unless $source eq $src;
                    next unless $r->{type} =~ /^(buy|sell)/;
                    $per_pair_rates{ $r->{pair} }{ $r->{type} } = $r->{rate};
                    $per_pair_rates{ $r->{pair} }{mtime} = $r->{mtime}
                        if $per_pair_rates{ $r->{pair} }{mtime} < $r->{mtime};
                }
                for my $pair (sort keys %per_pair_rates) {
                    push @rows, $per_pair_rates{$pair};
                }
            }
            $resmeta->{'table.fields'}        = ['source', 'pair', 'buy'  , 'sell' , 'mtime'           ];
            $resmeta->{'table.field_formats'} = [undef   , undef , $fnum8 , $fnum8 , 'iso8601_datetime'];
            $resmeta->{'table.field_aligns'}  = ['left'  , 'left', 'right', 'right', 'left'];
            if ($source =~ /\A\w+\z/) {
                shift @{ $resmeta->{'table.fields'} };
                shift @{ $resmeta->{'table.field_formats'} };
                shift @{ $resmeta->{'table.field_aligns'} };
            }
            $resmeta->{'table.field_align_code'}  = sub { $_[0] =~ /^(buy|sell)/ ? 'right' : undef },
            $resmeta->{'table.field_format_code'} = sub { $_[0] =~ /^(buy|sell)/ ? $fnum8  : undef },
        }

      FILTER_ROWS:
        {
            my @rows_f;
            for (@rows) {
                next if $pair && $_->{pair} ne $pair;
                push @rows_f, $_;
            }
            @rows = @rows_f;
        }

        [200, "OK", \@rows, $resmeta];

AUTHOR
    perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2021, 2018 by perlancar@cpan.org.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.