=encoding UTF-8

=head1 NAME

OpenTelemetry::Propagator - An abstract interface for OpenTelemetry propagators

=head1 SYNOPSIS

    use Object::Pad;

    class My::Propagator :does(OpenTelemetry::Propagator) {
        method extract { ... }
        method inject  { ... }
        method keys    { ... }
    }

    my $propagator = My::Propagator->new;

    # Inject data from the context to a carrier
    my $carrier = {};
    $propagator->inject( $carrier, $context );

    # Extract data from a carrier to the context
    my $new_context = $propagator->extract( $carrier, $context );

    # Reset the carrier for further operations
    delete @{$carrier}{ $propagator->keys };

=head1 DESCRIPTION

This package provides an L<Object::Pad> role that defines the interface
that OpenTelemetry propagator classes should implement. Propagators are
objects that can interact with the context (which can be either an
implicit or explicit instance of L<OpenTelemetry::Context>) and inject or
extract data using a variety of different formats.

It is the responsibility of propagator classes implementing this interface
to define those formats.

=head1 METHODS

Although there is unfortunately no way to currently enforce it, this document
describes the way the methods of a class implementing this role are expected
to behave.

=head2 inject

    $propagator = $propagator->inject(
        $carrier,
        $context // OpenTelemetry::Context->current,
        $setter  // OpenTelemetry::Propagator::TextMap::SETTER,
    )

Injects data from the context into a carrier. Must take a mandatory reference
to a carrier data structure into which the data will be injected, and an
optional instance of L<OpenTelemetry::Context> from where the data will be
read. If no context is provided, the current context must be used.

To support different kinds of carriers, a setter subroutine reference can be
passed as the third argument. This setter subroutine will be called with the
carrier and a key / value pair, and is expected to store the value under the
key in the carrier. If no setter is provided, classes implementing this
interface should provide a default setter that is suitable for their use case.

This method must return the calling propagator.

=head2 extract

    $new_context = $propagator->extract(
        $carrier,
        $context // OpenTelemetry::Context->current,
        $getter  // OpenTelemetry::Propagator::TextMap::GETTER,
    )

Extracts data from a carrier into the context. Must take a mandatory
reference to a carrier data structure from where the data will be extracted,
and an optional instance of L<OpenTelemetry::Context> into which the data will
be written. If no context is provided, the current context must be used.

To support different kinds of carriers, a getter subroutine reference can be
passed as the third argument. This getter will be called with the carrier and
a string to be used as a key, and is expected to return the value stored under
that key in the carrier. If no getter is provided, the default getter from
L<OpenTelemetry::Propagator::TextMap> will be used, which assumes the carrier
can be used as a hash reference.

This method must return a new instance of L<OpenTelemetry::Context> with the
values from the provided context, and holding the data extracted from the
carrier.

=head2 keys

    @keys = $propagator->keys

Returns the list of keys under which this propagator injects data into a
carrier. If the carrier needs to be cleared, these are the keys that need to be
deleted.

=head1 SEE ALSO

=over

=item L<OpenTelemetry::Context>

=item L<OpenTelemetry::Propagator::TextMap>

=item L<OpenTelemetry::Propagator::Composite>

=item L<OpenTelemetry::Propagator::Baggage>

=item L<OpenTelemetry::Propagator::TraceContext>

=back

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by José Joaquín Atria.

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