Pandoc

 view release on metacpan or  search on metacpan

lib/Pandoc/Version.pm  view on Meta::CPAN

package Pandoc::Version;
use 5.014;
use warnings;

our $VERSION = '0.9.2';

use overload
  '""'     => 'string',
  '0+'     => 'number',
  cmp      => 'cmp',
  '<=>'    => 'cmp',
  fallback => 1;
use Scalar::Util qw(reftype blessed);
use Pandoc::Error;

our @CARP_NOT = ('Pandoc');

sub new {
    my $class = shift;

    # We accept array or string input
    # (or mixed but let's not document that!)
    my @nums =
      map {
        my $num = $_;
        $num =~ /^\d+$/
          or Pandoc::Error->throw(
            message => 'invalid version number',
            version => $num
          );
        $num =~ s/^0+(?=\d)//;    # ensure decimal interpretation
        $num = 0 + $num;
        $num
      }
      map { s/^v//i; split /\./ }    ## no critic
      map { 'ARRAY' CORE::eq ( reftype $_ // "" ) ? @$_ : $_ }
      map { $_ // '' } @_;

    Pandoc::Error->throw('invalid version number') unless @nums;

    return bless \@nums => $class;
}

sub string { join '.', @{ $_[0] } }

sub number {
    my ( $major, @minors ) = @{ $_[0] };
    no warnings qw(uninitialized numeric);
    if (@minors) {
        my $minor = join '', map { sprintf '%03d', $_ } @minors;
        return 0 + "$major.$minor";    # return a true number
    }
    return 0 + $major;
}

sub cmp {
    my ( $a, $b ) = map {
        ( blessed $_ and $_->isa('Pandoc::Version') )
          ? $_
          : Pandoc::Version->new( $_ // () )
    } ( $_[0], $_[1] );
    return $a->number <=> $b->number;
}

sub match {
    my ( $a, $b ) = map { Pandoc::Version->new($_) } @_;
    pop @$a while @$a > @$b;
    pop @$b while @$b > @$a;

    return $a->number == $b->number;
}

my %cmp_truth_table = (
    '==' => [ 0, 1, 0 ],
    '!=' => [ 1, 0, 1 ],
    '>=' => [ 0, 1, 1 ],
    '<=' => [ 1, 1, 0 ],
    '<'  => [ 1, 0, 0 ],
    '>'  => [ 0, 0, 1 ]
);

sub fulfills {
    my ( $self, $req ) = @_;
    return 1 unless $req;

    my @parts = split qr{\s*,\s*}, $req;
    for my $part (@parts) {
        my ( $op, $ver ) =
          $part =~ m{^\s*(==|>=|>|<=|<|!=)?\s*v?(\d+(\.\d+)*)$};
        if ( !defined $ver ) {
            Pandoc::Error->throw(
                message => "invalid version requirement: $req",
                require => $req,
            );
        }

        my $cmp = $self->cmp($ver) + 1;    # will be 0 for <, 1 for ==, 2 for >
        return unless $cmp_truth_table{ $op || '>=' }->[$cmp];
    }

    1;

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.583 second using v1.00-cache-2.02-grep-82fe00e-cpan-f5108d614456 )