summaryrefslogtreecommitdiff
path: root/lib/ACME/AutoRedact.pm
blob: 0b85712bbb5e8371a4a6354dee38b4fa7174af98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package ACME::AutoRedact; 
use strict;
use warnings;
# VERSION 
use Scope::Upper qw(localize :words);
use Scalar::Util qw(blessed);
 
# ABSTRACT: string-like object that can redact its value out of derived strings 
 
use overload
    q{""} => \&stringify,
    q{.} => \&concat,
    fallback => 1,
    ;
 
sub _build__redacted {
    my ($self) = @_;
    return '*' x length($self->{value});
}
 
sub new {
    my ($class,@args) = @_;
 
    my $self;
    if (@args==1 and not ref $args[0]) {
        $self = { value => $args[0] };
    }
    elsif (@args==1) {
        $self = $args[0];
    }
    else {
        $self = { @args };
    }
    bless $self,$class;
    $self->{_redacted//$self->_build__redacted;
    return $self;
}
 
our $requested_behaviour;
 
sub redact {
    localize *requested_behaviour, \'redact', UP;
}
 
sub reveal {
    localize *requested_behaviour, \'reveal', UP;
}
 
sub stringify {
    my ($self) = @_;
 
    my $behaviour = $requested_behaviour // $self->{default_behaviour// 'reveal';
 
    if ($behaviour eq 'reveal') {
        return $self->{value};
    }
    else {
        return $self->{_redacted};
    }
}
 
sub concat {
    my ($self,$other,$swap) = @_;
 
    my %new;
    if ((blessed($other)//''eq __PACKAGE__) {
        $new{value} = $swap
            $other->{value} . $self->{value}
            $self->{value} . $other->{value};
        $new{_redacted} = $swap
            $other->{_redacted} . $self->{_redacted}
            $self->{_redacted} . $other->{_redacted};
 
        $new{default_behaviour} = $swap
            $other->{default_behaviour}
            $self->{default_behaviour};
    }
    else {
        $new{value} = $swap
            "$other" . $self->{value}
            $self->{value} . "$other";
        $new{_redacted} = $swap
            "$other" . $self->{_redacted}
            $self->{_redacted} . "$other";
        $new{default_behaviour} = $self->{default_behaviour};
    }
 
    return ref($self)->new(\%new);
}
 
1;