summaryrefslogtreecommitdiffstats
path: root/lib/Bread/Board.pm
blob: c3d1a26348badf07ee8056f5c3c42af48136b099 (plain) (blame)
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
use v6;

class Bread::Board::Dependency {...}

role Bread::Board::Service {
    has Str $.name;

    # XXX not sure how to make these optional - specifying the types here
    # makes it fail when the parameters aren't passed
    # shouldn't the " = {}" part be taking care of that?
    # has Hash of Bread::Board::Dependency $.dependencies = {};
    # has Hash of Hash $.parameters = {};
    has $.dependencies = {};
    has $.parameters = {};

    # XXX overriding new here is an extremely suboptimal solution
    # does perl 6 have anything like moose's coercions?
    method new (*%params is copy) {
        if %params.<dependencies> {
            my $deps = {};
            for %params.<dependencies>.keys -> $dep {
                $deps.{$dep} = Bread::Board::Dependency.new(
                    service => %params.<dependencies>.{$dep},
                );
            }
            %params.<dependencies> = $deps;
        }
        nextwith(|%params);
    }

    method get {*};

    method get_dependency ($name) {
        return $.dependencies.{$name};
    }
}

class Bread::Board::Dependency {
    has Bread::Board::Service $.service handles 'get';
}

class Bread::Board::ConstructorInjection does Bread::Board::Service {
    has $.class;
    has Str $.constructor_name is rw = 'new';

    method get (*%params is copy) {
        self.check_parameters(%params);
        for $.dependencies.keys -> $name {
            %params{$name} = $.dependencies{$name}.get;
        }
        return $.class."$.constructor_name"(|%params);
    }

    my method check_parameters (%params) {
        for $.parameters.keys -> $name {
            if not %params.{$name}:exists {
                die "Required parameter $name not given";
            }
        }

        for %params.keys -> $name {
            if not $.parameters.{$name}:exists {
                die "Unknown parameter $name given";
            }
            if not %params.{$name}.isa($.parameters.{$name}.<isa>) {
                die "{%params.{$name}.perl} is not a valid value for the $name parameter";
            }
        }

        # XXX why is this return necessary?
        return;
    }
}

class Bread::Board::Literal does Bread::Board::Service {
    has $.value;

    method get {
        return $.value;
    }
}