# frozen_string_literal: true

Puppet::Parser::Functions.newfunction(
  :assert_type,
  :type => :rvalue,
  :arity => -3,
  :doc => <<~DOC
    Returns the given value if it is of the given
    [data type](https://puppet.com/docs/puppet/latest/lang_data.html), or
    otherwise either raises an error or executes an optional two-parameter
    [lambda](https://puppet.com/docs/puppet/latest/lang_lambdas.html).

    The function takes two mandatory arguments, in this order:

    1. The expected data type.
    2. A value to compare against the expected data type.

    **Example**: Using `assert_type`

    ~~~ puppet
    $raw_username = 'Amy Berry'

    # Assert that $raw_username is a non-empty string and assign it to $valid_username.
    $valid_username = assert_type(String[1], $raw_username)

    # $valid_username contains "Amy Berry".
    # If $raw_username was an empty string or a different data type, the Puppet run would
    # fail with an "Expected type does not match actual" error.
    ~~~

    You can use an optional lambda to provide enhanced feedback. The lambda takes two
    mandatory parameters, in this order:

    1. The expected data type as described in the function's first argument.
    2. The actual data type of the value.

    **Example**: Using `assert_type` with a warning and default value

    ~~~ puppet
    $raw_username = 'Amy Berry'

    # Assert that $raw_username is a non-empty string and assign it to $valid_username.
    # If it isn't, output a warning describing the problem and use a default value.
    $valid_username = assert_type(String[1], $raw_username) |$expected, $actual| {
      warning( "The username should be \'${expected}\', not \'${actual}\'. Using 'anonymous'." )
      'anonymous'
    }

    # $valid_username contains "Amy Berry".
    # If $raw_username was an empty string, the Puppet run would set $valid_username to
    # "anonymous" and output a warning: "The username should be 'String[1, default]', not
    # 'String[0, 0]'. Using 'anonymous'."
    ~~~

    For more information about data types, see the
    [documentation](https://puppet.com/docs/puppet/latest/lang_data.html).

    - Since 4.0.0
  DOC
) do |_args|
  Puppet::Parser::Functions::Error.is4x('assert_type')
end
