openai-async/lib/OpenAIAsync/Types.pm
Ryan Voots 574ac17d07
Some checks failed
ci/woodpecker/push/author-tests Pipeline failed
Getting there
2023-12-31 17:30:31 -05:00

97 lines
2.7 KiB
Perl

package OpenAIAsync::Types;
use v5.36.0;
use Object::Pad;
use Object::PadX::Role::AutoMarshal;
use Object::PadX::Role::AutoJSON;
use Object::Pad::ClassAttr::Struct;
# Base role for all the types to simplify things later
role OpenAIAsync::Types::Base :does(Object::PadX::Role::AutoJSON) :does(Object::PadX::Role::AutoMarshal) :Struct {
use JSON::MaybeXS qw//;
our $_json = JSON::MaybeXS->new(utf8 => 1, convert_blessed => 1);
method _encode() {
return $_json->encode($self);
}
}
# Keep the JSON role stuff here, I might use it to annotate encodings of some non-json fields? not sure
role OpenAIAsync::Types::BaseFormEncoding :does(Object::PadX::Role::AutoJSON) :does(Object::PadX::Role::AutoMarshal) :Struct {
use WWW::Form::UrlEncoded;
use Object::Pad::MOP::FieldAttr;
use Object::Pad::MOP::Field;
use Object::Pad::MOP::Class;
my $_to_str = sub ($x) {
return "".$x;
};
my $_to_num = sub ($x) {
return 0+$x;
};
my $_to_bool = sub ($x) {
return !!$x ? \1 : \0;
};
my $_to_list = sub ($ref, $type) {
my $sub = $type eq 'JSONNum' ? $_to_num :
$type eq 'JSONStr' ? $_to_str :
$type eq 'JSONBool' ? $_to_bool :
sub {die "Wrong type $type in json conversion"};
return [map {$sub->($_)} $ref->@*]
};
method _as_hash() {
my $class = __CLASS__;
my $classmeta = Object::Pad::MOP::Class->for_class($class);
my @metafields = $classmeta->fields;
my %json_out = ();
for my $metafield (@metafields) {
my $field_name = $metafield->name;
my $sigil = $metafield->sigil;
my $has_exclude = $metafield->has_attribute("JSONExclude");
next if $has_exclude;
next if $sigil ne '$'; # Don't try to handle anything but scalars
my $has_null = $metafield->has_attribute("JSONNull");
my $value = $metafield->value($self);
next unless (defined $value || $has_null);
my $key = $field_name =~ s/^\$//r;
$key = $metafield->get_attribute_value("JSONKey") if $metafield->has_attribute("JSONKey");
if ($metafield->has_attribute('JSONBool')) {
$value = $_to_bool->($value);
} elsif ($metafield->has_attribute('JSONNum')) {
# Force numification
$value = $_to_num->($value);
} elsif ($metafield->has_attribute('JSONList')) {
my $type = $metafield->get_attribute_value('JSONList');
$value = $_to_list->($value, $type);
} else {
# Force stringification
$value = $_to_str->($value);
}
$json_out{$key} = $value;
}
return \%json_out;
}
method _encode() {
my $hash = $self->_as_hash();
my $string = WWW::Form::UrlEncoded::build_urlencoded($hash);
return $string;
}
}