require Carp;
require Carp::Heavy;

use APR::Util ();

use overload
    nomethod => \&fatal,
    'bool'   => \&str,
    '=='     => \&num,
    '0+'     => \&num,
    '""'     => \&str;

sub fatal {  die __PACKAGE__ . ": Can't handle '$_[3]'" }

# normally the object is created on the C side, but if you want to
# create one from Perl, you can. just pass a hash with args:
# rc, file, line, func
sub new {
    my $class = shift;
    my %args = @_;
    bless \%args, $class;
}

sub str {
    sprintf "%s: %s at %s line %d", $_[0]->{func},
        APR::Error::strerror($_[0]->{rc}),
        $_[0]->{file}, $_[0]->{line};
}

sub num { $_[0]->{rc} }

# skip the wrappers from this package from the long callers trace
$Carp::CarpInternal{+__PACKAGE__}++;

# XXX: Carp::(confess|cluck) see no calls stack when Perl_croak is
# called with Nullch (which is the way execption objects are
# returned), so we fixup it here (doesn't quite work for croak
# caller).
sub cluck {
    if (ref $_[0] eq __PACKAGE__) {
        Carp::cluck("$_[0]->{func}: " .
                    APR::Error::strerror($_[0]->{rc}));
    }
    else {
        &Carp::cluck;
    }
}

sub confess {
    if (ref $_[0] eq __PACKAGE__) {
        Carp::confess("$_[0]->{func}: " .
                    APR::Error::strerror($_[0]->{rc}));
    }
    else {
        &Carp::confess;
    }
}

1;
__END__
