.. _tutorial_regexp:

Regexp type with calculation
============================

.. objectives:: Objectives

   Regexp is a :ref:`variable specialize type <variable>` which allows for easy validation of a variable from a regular expression.

.. prerequisites:: Prerequisites

    - We assume that Rougail's library is :ref:`installed <installation>` on your computer.

    - It is possible to retrieve the current state of the various Rougail files manipulated in this tutorial step
      by checking out the corresponding tag of the `rougail-tutorials` git repository.
      Each tag corresponds to a stage of progress in the tutorial.
      Of course, you can also decide to copy/paste or download the tutorial files contents while following the tutorial steps.

    If you want to follow this tutorial with the help of the corresponding :tutorial:`rougail-tutorials git repository <src/branch/1.1>`, 
    this workshop page corresponds to the tags :tutorial:`v1.1_200 <src/tag/v1.1_200/README.md>` to :tutorial:`v1.1_201 <src/tag/v1.1_201/README.md>` 

    ::
   
       git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git
       git switch --detach v1.1_200

A regexp variable
-----------------

We have already seen the :ref:`validator mechanism <tutorial_validators>` for managing the :ref:`quality of data values <data_quality>`.

This mechanism is undeniably interesting and powerful.
But for strings that can be validated using a regular expression, it is preferable to use this type.
In this specific case, nothing beats this particular type.

Obviously, the values assigned to a regexp type variable must be of type string.

Here we will add a `color` variable which will allow us to quickly identify the current proxy via a color code. The expected value is a hex color code (like those used in CSS or HTML).

This regrex must validate that the string begins with a hash symbol (#) followed by a RGB triplet in hexadecimal format (so 3 or 6 lowercase hexadecimal digits (0–9, a–f)).

Here are some examples: `#a3f09c` or `#a3f`.

The regular expression is `^#(?:[0-9a-f]{3}){1,2}$`.

Let's write this variable:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_200/foxyproxy/00-foxyproxy.yml
   :language: yaml
   :caption: The regexp variable `color`.

Now let's test with the following user data file:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_200/config/02/config.yml
   :linenos:
   :language: yaml
   :caption: The :file:`config/02/config.yml` user data

With this Rougail CLI: 

.. raw:: html
   :class: terminal
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_200/config/02/cmd_ro.txt

We have this output: 

.. raw:: html
   :class: output
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_200/config/02/output_ro.html

What happens if the value is not valid?

The value is invalid:

.. raw:: html
   :class: output
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_200/config/03/output_ro.html

Calculate a random color
------------------------

.. type-along:: For those who follow the tutorial with the help of the git repository

    Now you need to checkout the :tutorial:`v1.1_201 <src/tag/v1.1_201/README.md>` version::
     
          git switch --detach v1.1_201

Why not offer a default value to the user?

If the user has a specific color in mind, they can specify it. Otherwise, Rougail will suggest a default value.

We've already seen how to use :ref:`Jinja <tutorial_jinja>` for :ref:`validation <tutorial_validators>` and :ref:`access control <tutorial_disabled>` calculations.

We've also seen how to calculate the default value by :ref:`retrieving the value of another variable <tutorial_calc_variable>`.

It's entirely possible to calculate the default value from a Jinja template:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_201/foxyproxy/00-foxyproxy.yml
   :language: yaml
   :caption: Calculate the default variable `color`.

Now let's test with the following user data file:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_201/config/02/config.yml
   :linenos:
   :language: yaml
   :caption: The :file:`config/02/config.yml` user data

With this Rougail CLI: 

.. raw:: html
   :class: terminal
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_201/config/02/cmd_ro.txt

We have this output:

.. raw:: html
   :class: output
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_201/config/02/output_ro.html

As you can see, Rougail offers a default value!

.. keypoints:: Key points

   - We can easily create a variable that valid value via a regexp
   - We can calculate a default value with Jinja template
