File: datetime-coercions.pl

package info (click to toggle)
libtype-tiny-perl 2.002001-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,948 kB
  • sloc: perl: 14,610; makefile: 2; sh: 1
file content (123 lines) | stat: -rw-r--r-- 2,734 bytes parent folder | download | duplicates (2)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
=pod

=encoding utf-8

=head1 PURPOSE

This example expands upon the Example::Types library defined in
L<Type::Tiny::Manual::Libraries>. It defines class types for L<DateTime>
and L<DateTime::Duration> and some structured types for hashes that
can be used to instantiate DateTime objects. It defines some coercions
for the C<Datetime> class type.

A simple L<Moose> class is provided using some of these types and
coercions. The class also defines a couple of extra coercions inline.

See the source code of this file for the actual example code.

=head1 DEPENDENCIES

L<Moose>, L<DateTime>.

=head1 AUTHOR

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2013-2022 by Toby Inkster.

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

=cut

use strict;
use warnings;
use lib "lib", "../lib";

BEGIN {
	package Example::Types;
	
	use Type::Library
		-base,
		-declare => qw( Datetime DatetimeHash Duration EpochHash );
	use Type::Utils;
	use Types::Standard -types;
	
	require DateTime;
	require DateTime::Duration;
	
	class_type Datetime, { class => "DateTime" };
	
	class_type Duration, { class => "DateTime::Duration" };
	
	declare DatetimeHash,
		as Dict[
			year       => Int,
			month      => Optional[ Int ],
			day        => Optional[ Int ],
			hour       => Optional[ Int ],
			minute     => Optional[ Int ],
			second     => Optional[ Int ],
			nanosecond => Optional[ Int ],
			time_zone  => Optional[ Str ],
		];
	
	declare EpochHash,
		as Dict[
			epoch      => Int,
			time_zone  => Optional[ Str ],
		];
	
	coerce Datetime,
		from Int,          via { "DateTime"->from_epoch(epoch => $_) },
		from Undef,        via { "DateTime"->now },
		from DatetimeHash, via { "DateTime"->new(%$_) },
		from EpochHash,    via { "DateTime"->from_epoch(%$_) };
	
	$INC{"Example/Types.pm"} = __FILE__;
};

BEGIN {
	package Person;
	
	use Moose;
	use Types::Standard qw( Str Int Num );
	use Example::Types qw( Datetime Duration );
	
	has name => (
		is       => "ro",
		isa      => Str,
		required => 1,
	);
	
	has age => (
		is       => "ro",
		isa      => Int->plus_coercions(Num, 'int($_)', Duration, '$_->years'),
		coerce   => 1,
		init_arg => undef,
		lazy     => 1,
		builder  => "_build_age",
	);
	
	has date_of_birth => (
		is       => "ro",
		isa      => Datetime,
		coerce   => 1,
		required => 1,
	);
	
	sub _build_age
	{
		my $self = shift;
		return Datetime->class->now - $self->date_of_birth;
	}
};

my $me = Person->new(
	name          => "Toby Inkster",
	date_of_birth => { epoch => 328646500, time_zone => "Asia/Tokyo" },
);

printf("%s is %d years old.\n", $me->name, $me->age);