--- /dev/null
+package Data::Query::Constants;
+
+use strictures 1;
+use Exporter 'import';
+
+use constant +{
+ (our %CONST = (
+ DQ_IDENTIFIER => 'Identifier',
+ ))
+};
+
+our @EXPORT_OK = keys our %CONST;
+
+1;
--- /dev/null
+package Data::Query::ExprBuilder;
+
+use strictures 1;
+
+sub new {
+ bless({ %{$_[1]} }, (ref($_[0])||$_[0]));
+}
+
+1;
--- /dev/null
+package Data::Query::ExprBuilder::Identifier;
+
+use strictures 1;
+
+use base qw(Data::Query::ExprBuilder);
+use Data::Query::Constants qw(DQ_IDENTIFIER);
+
+sub DESTROY { }
+
+sub can {
+ my $name = $_[1];
+ sub {
+ return (ref($_[0])||$_[0])->new({
+ expr => {
+ type => DQ_IDENTIFIER,
+ elements => [ @{$_[0]->{expr}{elements}}, $name ]
+ },
+ });
+ };
+}
+
+sub AUTOLOAD {
+ (my $auto = our $AUTOLOAD) =~ s/.*:://;
+ return (ref($_[0])||$_[0])->new({
+ expr => {
+ type => DQ_IDENTIFIER,
+ elements => [ @{$_[0]->{expr}{elements}}, $auto ]
+ },
+ });
+}
+
+1;
--- /dev/null
+use strictures 1;
+use Test::More qw(no_plan);
+use Data::Query::ExprBuilder::Identifier;
+use Data::Query::Constants qw(DQ_IDENTIFIER);
+
+sub mk_expr {
+ local $_ = Data::Query::ExprBuilder::Identifier->new({
+ expr => {
+ type => DQ_IDENTIFIER,
+ elements => [],
+ },
+ });
+ $_[0]->()->{expr};
+}
+
+sub expr_is (&;@) {
+ my $sub = shift;
+ is_deeply(mk_expr($sub), @_);
+}
+
+expr_is { $_->foo }
+ {
+ type => DQ_IDENTIFIER,
+ elements => [ 'foo' ]
+ },
+ 'Simple identifier ok';
+
+
+expr_is { $_->foo->bar }
+ {
+ type => DQ_IDENTIFIER,
+ elements => [ 'foo', 'bar' ]
+ },
+ 'Nested identifier ok';