NAME

JSON::Schema::Modern::Utilities - Internal utilities for JSON::Schema::Modern

VERSION

version 0.638

SYNOPSIS

use JSON::Schema::Modern::Utilities qw(func1 func2..);

DESCRIPTION

This class contains internal utilities to be used by JSON::Schema::Modern, and other useful helpers.

FUNCTIONS

is_type

if (is_type('string', $value)) { ... }

Returns a boolean indicating whether the provided value is of the specified core type (null, boolean, string, number, object, array) or integer. Also optionally takes a hashref { legacy_ints = 1 }> indicating that draft4 number semantics should apply (where unlike later drafts, 2.0 is not an integer).

get_type

my $type = get_type($value);

Returns one of the core types (null, boolean, string, number, object, array) or integer. Also optionally takes a hashref { legacy_ints = 1 }> indicating that draft4 number semantics should apply. Behaviour is consistent with "is_type".

is_bool

if (is_bool($value)) { ... }

Equivalent to is_type('boolean', $value). Accepts JSON booleans and builtin booleans, but not dualvars (because JSON encoders do not recognize these as booleans).

is_schema

if (is_schema($value)) { ... }

Equivalent to is_type('object') || is_type('boolean').

is_equal

if (not is_equal($x, $y, my $state = {})) {
  say "values differ starting at $state->{path}: $state->{error}";
}

Compares two arbitrary data payloads for equality, as per Instance Equality in the JSON Schema draft2020-12 specification.

The optional third argument hashref supports the following fields:

  • scalarref_booleans (provided by caller input): as in "scalarref_booleans" in JSON::Schema::Modern

  • stringy_numbers (provided by caller input): when set, strings will also be compared numerically, as in "stringy_numbers" in JSON::Schema::Modern

  • path (populated by function): if result is false, the json pointer location of the first difference

  • error (populated by function): if result is false, an error description of the first difference

is_elements_unique

if (not is_elements_unique($arrayref, my $state = {}) {
  say "lists differ starting at $state->{path}: $state->{error}";
}

Compares all elements of an arrayref for uniqueness.

The optional second argument hashref supports the same options as "is_equal", plus:

  • equal_indices (populated by function): if result is false, the list of indices of the (first set of) equal items found.

jsonp

# '/paths/~1foo~1{foo_id}/get/responses'
my $jsonp = jsonp(qw(/paths /foo/{foo_id} get responses));

Constructs a json pointer string from a list of path components, with correct escaping; the first argument must be '' or an already-escaped json pointer, to which the rest of the path components are appended.

unjsonp

# ('', 'paths', '/foo/{foo_id}', 'get', 'responses')
my @components = unjsonp('/paths/~1foo~1{foo_id}/get/responses');

Splits a json pointer string into its path components, with correct unescaping.

jsonp_get

# 4
my $val = jsonp_get({ a => 1, b => { c => 3, d => 4 } }, '/b/d');

Fetches the value of a data structure at a particular json pointer location.

jsonp_elements

# {
#   '/a/b/0' => 'x',
#   '/a/b/1' => 'y',
#   '/a/c/d' => 'e',
# }
jsonp_elements({ a => { b => [ 'x', 'y' ], c => { d => 'e' } } });

Fetches all the ( json pointer => value ) tuples of a data structure as a hashref.

jsonp_set

my $data = { a => 1, b => { c => 3, d => 4 } };
my $defaults = {
  '/b/d' => 5,
  '/b/e' => 6,
  '/f' => 7,
  '/g/h/i/1' => [ 10 ],
};
jsonp_set($data, $_, $defaults->{$_}) foreach keys %$defaults;

# data is now:
# { a => 1, b => { c => 3, d => 5, e => 6 }, f => 7, g => { h => { i => [ undef, [ 10 ] ] } } }

Given an arbitrary data structure, a json pointer string, and an arbitrary value, assigns that value to the given position in the data structure. This is a destructive operation, overwriting whatever data was there before if needed (even if an incompatible type: e.g. a hash key will overwrite an existing arrayref). Intermediary keys or indexes will spring into existence as needed.

json_pointer_type

A Type::Tiny type representing a json pointer string.

canonical_uri_type

A Type::Tiny type representing a canonical URI: a Mojo::URL with either no fragment, or with a json pointer fragment.

core_types_type

A Type::Tiny type representing the core JSON Schema types.

core_formats_type

A Type::Tiny type representing the core JSON Schema formats (across all supported versions).

load_cached_document

my $evaluator = JSON::Schema::Modern->new;
my $uri = 'https://json-schema.org/draft-07/schema#';
my $document = load_cached_document($evaluator, $uri);

my $result = $evaluator->evaluate($data, $uri);

Loads a document object from global cache, loading data from disk if needed. This should only be used for officially-published schemas and metaschemas that are bundled with this distribution or another related one.

add_media_type

add_media_type('application/my_zip', $decoder_sub, $encoder_sub);
add_media_type('audio/*; version=1', $decoder_sub, $encoder_sub);

Adds a media-type entry to the registry, or replaces an existing one. This registry is runtime-global, available to any code running in this process.

Either or both of the subrefs are optional (use undef for the decoder sub if you only want an encoder); the subref is expected to have the following signature:

sub ($content_ref, $parameters = {}, @)

The subref will be called with a reference to the content string, and a hashref of the parameters that were parsed from the Content-Type header (if any). Extra arguments are allowed to allow for future flexibility with this interface.

These media types are already defined:

Media-type definitions can be overridden with a new call to add_media_type.

See the official OpenAPI Media Type Registry for a registry of known and useful media types; for compatibility reasons, avoid defining a media type listed here with different semantics.

delete_media_type

delete_media_type('application/my_zip');

Removes a media-type entry from the registry. The string must match exactly, including case and whitespace.

decode_media_type

my $content_ref = decode_media_type('text/plain; charset=UTF-8', \'encoded text');

Finds the best-matching media-type decoder for the given media-type and decodes the content (which must be passed as a reference); returns a reference to the decoded content, or undef if no matching decoder could be found. An exception might be thrown if the data could not be successfully decoded.

encode_media_type

my $content_ref = encode_media_type('text/plain; charset=UTF-8', \[ 'decoded content' ]);

Finds the best-matching media-type encoder for the given media-type and encodes the content (which must be passed as a reference); returns a reference to the encoded content, or undef if no matching encoder could be found. An exception might be thrown if the data could not be successfully encoded.

match_media_type

my $registered_media_type = match_media_type('text/html');
my $ad_hoc_media_type = match_media_type('text/html', [ 'text/plain', 'text/*' ]);

Finds the best match for a Content-Type header value from the media-types in the registry, or from an ad-hoc list reference provided in the remaining arguments.

Types with structured suffixes will match more generic types when an exact match is not available (e.g. application/schema+json will match an entry for application/json).

Exact matches to the type/subtype name are preferred over wildcard matches (e.g. text/*); if parameters are present in the value being matched against (the list of registered media-types, or the list provided to this sub), all parameters must be present and match exactly.

All comparisons are done case-insensitively.

GIVING THANKS

If you found this module to be useful, please show your appreciation by adding a +1 in MetaCPAN and a star in GitHub.

SUPPORT

Bugs may be submitted through https://github.com/karenetheridge/JSON-Schema-Modern/issues.

I am also usually active on irc, as 'ether' at irc.perl.org and irc.libera.chat.

You can also find me on the JSON Schema Slack server and OpenAPI Slack server, which are also great resources for finding help.

AUTHOR

Karen Etheridge <ether@cpan.org>

COPYRIGHT AND LICENCE

This software is copyright (c) 2020 by Karen Etheridge.

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

Some schema files have their own licence, in share/LICENSE.