1nickt has asked for the wisdom of the Perl Monks concerning the following question:

Greetings brethren and sistren,

I'm replacing some uses of JSON::Validator with Type::Tiny, and have run into a hurdle, where our JSON validation code can make use of anyOf and oneOf (and even if ... else ... then).

I'm think of ways I could accomplish similar functionality using Type::Tiny. Constraints? Is there a trick I don't know about (I'm certainly not a Type::Tiny expert)?

Thanks for any help!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re: Type::Tiny and anyOf, oneOf
by choroba (Cardinal) on Feb 02, 2021 at 13:29 UTC
    Not directly answering your question, but have you considered Cpanel::JSON::XS::Type?
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Thanks choroba, I was not aware of this module. Looks like it could be useful, but in this case I am not producing or deserializing JSON, just wanting to validate a subroutine's args.

      The way forward always starts with a minimal test.
Re: Type::Tiny and anyOf, oneOf
by tobyink (Canon) on Feb 02, 2021 at 23:46 UTC

    Not exactly sure what you want to accomplish but "any of" sounds like a union:

    use Types::Standard qw( ArrayRef HashRef ScalarRef ); my ( @thing1, %thing2, $thing3 ); my $union = ArrayRef | HashRef; $union->check( \@thing1 ); # true $union->check( \%thing1 ); # true $union->check( \$thing1 ); # false ( ArrayRef | HashRef | ScalarRef )->check( \$thing1 ); # true

      Thanks Toby. It probably can't be accomplished with a type. With a JSON Schema you can say about an object (Dict) that it must contain one of a list of (named) keys each with their own type. You could require either a phone number or an email address, for example. So something like:

      my $check = compile(Dict[ foo => Str, oneOf => [ baz => Int, qux => Str, ], ]);


      The way forward always starts with a minimal test.
Re: Type::Tiny and anyOf, oneOf
by Anonymous Monk on Feb 03, 2021 at 10:52 UTC