## dist_zef-grizzlysmit-Gzz-Text-Utils.md
## Chunk 1 of 2
## Table of Contents

* [NAME](#name)
* [AUTHOR](#author)
* [VERSION](#version)
* [TITLE](#title)
* [SUBTITLE](#subtitle)
* [COPYRIGHT](#copyright)
* [Introduction](#introduction)

  * [Motivations](#motivations)

    * [Update](#update)
* [Exceptions](#exceptions)

  * [BadArg](#badarg)
  * [ArgParityMissMatch](#argparitymissmatch)
  * [FormatSpecError](#formatspecerror)
* [`UnhighlightBase` & `UnhighlightBaseActions` and `Unhighlight` & `UnhighlightActions`](#unhighlightbase--unhighlightbaseactions-and-unhighlight--unhighlightactions)
* [The Functions Provided](#the-functions-provided)

  * [Here are 4 functions provided to **`centre`**, **`left`** and **`right`** justify text even when it is ANSI formatted](#here-are-4-functions-provided-to-centre-left-and-right-justify-text-even-when-it-is-ansi-formatted)

    * [centre(…)](#centre)
    * [left(…)](#left)
    * [right(…)](#right)

      * [crop-field(…)](#crop-field)
  * [Sprintf](#sprintf)
  * [Printf](#printf)
  * [MultiT](#multit)
  * [menu(…)](#menu)
  * [input-menu(…)](#input-menu)
  * [dropdown(…)](#dropdown)
  * [lead-dots(…)](#lead-dots)
  * [trailing-dots(…)](#trailing-dots)
  * [dots(…)](#dots)

# NAME

Gzz::Text::Utils

# AUTHOR

Francis Grizzly Smit ([grizzly@smit.id.au](mailto:grizzly@smit.id.au))

# VERSION

v0.1.23

# TITLE

Gzz::Text::Utils

# SUBTITLE

A Raku module to provide text formatting services to Raku programs.

# COPYRIGHT

LGPL V3.0+ [LICENSE](https://github.com/grizzlysmit/Gzz-Text-Utils/blob/main/LICENSE)

# Introduction

A Raku module to provide text formatting services to Raku programs.

Including a sprintf front-end Sprintf that copes better with Ansi highlighted text and implements **`%U`** and does octal as **`0o123`** or **`0O123`** if you choose **`%O`** as I hate ambiguity like **`0123`** is it an int with leading zeros or an octal number. Also there is **`%N`** for a new line and **`%T`** for a tab helpful when you want to use single quotes to stop the **`$`** specs needing back slashes.

And a **`printf`** alike **`Printf`**.

Also it does centring and there is a **`max-width`** field in the **`%`** spec i.e. **`%*.*.*E`**, and more.

[Top of Document](#table-of-contents)

## Motivations

When you embed formatting information into your text such as **bold**, *italics*, etc ... and **colours** standard text formatting will not work e.g. printf, sprintf etc also those functions don't do centring.

Another important thing to note is that even these functions will fail if you include such formatting in the **text** field unless you supply a copy of the text with out the formatting characters in it in the **:ref** field i.e. **`left($formatted-text, $width, :ref($unformatted-text))`** or **`text($formatted-text, $width, :$ref)`** if the reference text is in a variable called **`$ref`** or you can write it as **`left($formatted-text, $width, ref => $unformatted-text)`**

[Top of Document](#able-of-contents)

### Update

Fixed the proto type of **`left`** etc is now

```
sub left(Str:D $text, Int:D $width is copy, Str:D $fill = ' ',
            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &left-global-number-of-chars,
               Str:D :$ref = strip-ansi($text), Int:D
                                :$max-width = 0, Str:D :$ellipsis = '' --> Str) is export

```

Where **`sub strip-ansi(Str:D $text --> Str:D) is export`** is my new function for striping out ANSI escape sequences so we don't need to supply **`:$ref`** unless it contains codes that **`sub strip-ansi(Str:D $text --> Str:D) is export`** cannot strip out, if so I would like to know so I can update it to cope with these new codes.

[Top of Document](#table-of-contents)

# Exceptions

## BadArg

```
class BadArg is Exception is export

```

BadArg is a exception type that Sprintf will throw in case of badly specified arguments.

[Top of Document](#table-of-contents)

## ArgParityMissMatch

```
class ArgParityMissMatch is Exception is export

```

ArgParityMissMatch is an exception class that Sprintf throws if the number of arguments does not match what the number the format string says there should be.

**NB: if you use *`num$`* argument specs these will not count as they grab from the args add hoc, *`*`* width and precision spec however do count as they consume argument.**

[Top of Document](#table-of-contents)

## FormatSpecError

```
class FormatSpecError is Exception is export

```

FormatSpecError is an exception class that Format (used by Sprintf) throws if there is an error in the Format specification (i.e. **`%n`** instead of **`%N`** as **`%n`** is already taken, the same with using **`%t`** instead of **`%T`**).

Or anything else wrong with the Format specifier.

**NB: *`%N`* introduces a *`\n`* character and *`%T`* a tab (i.e. *`\t`*).**

[Top of Document](#table-of-contents)

# Format and FormatActions

Format & FormatActions are a grammar and Actions pair that parse out the **%** spec and normal text chunks of a format string.

For use by Sprintf a sprintf alternative that copes with ANSI highlighted text.

[Top of Document](#table-of-contents)

# `UnhighlightBase` & `UnhighlightBaseActions` and `Unhighlight` & `UnhighlightActions`

**`UnhighlightBase`** & **`UnhighlightBaseActions`** are a grammar & role pair that does the work required to to parse apart ansi highlighted text into ANSI highlighted and plain text.

**`Unhighlight`** & **`UnhighlightActions`** are a grammar & class pair which provide a simple TOP for applying an application of **`UnhighlightBase`** & **`UnhighlightBaseActions`** for use by **`sub strip-ansi(Str:D $text --` Str:D) is export**> to strip out the plain text from a ANSI formatted string

[Top of Document](#table-of-contents)

# The Functions Provided

* strip-ansi

  ```
  sub strip-ansi(Str:D $text --> Str:D) is export

  ```

  Strips out all the ANSI escapes, at the moment just those provided by the **`Terminal::ANSI`** or **`Terminal::ANSI::OO`** modules both available as **`Terminal::ANSI`** from zef etc I am not sure how exhaustive that is, but I will implement any more escapes as I become aware of them.
* hwcswidth

  ```
  sub hwcswidth(Str:D $text --> Int:D) is export

  ```

  Same as **`wcswidth`** but it copes with ANSI escape sequences unlike **`wcswidth`**.

  * The secret sauce is that it is defined as:

    ```
    sub hwcswidth(Str:D $text --> Int:D) is export {
        return wcswidth(strip-ansi($text));
    } #  sub hwcswidth(Str:D $text --> Int:D) is export #

    ```

[Top of Document](#table-of-contents)

### Here are 4 functions provided to **`centre`**, **`left`** and **`right`** justify text even when it is ANSI formatted.

### centre

* ⋄

  * Centring text in a field.

    ```
    sub centre(Str:D $text,
               Int:D $width is copy,
               Str:D $fill = ' ',
               :&number-of-chars:(Int:D, Int:D --> Bool:D) =
                                   &centre-global-number-of-chars,
               Str:D :$ref = strip-ansi($text),
               Int:D :$max-width = 0,
               Str:D :$ellipsis = '' --> Str) is export {

    ```

    * Centres the text **`$text`** in a field of width **`$width`** padding either side with **`$fill`**
    * **Where:**

      * **`$fill`** is the fill char by default **`$fill`** is set to a single white space.

        * If it requires an odd number of padding then the right hand side will get one more char/codepoint.
      * **`&number-of-chars`** takes a function which takes 2 **`Int:D`**'s and returns a **`Bool:D`**.

        * By default this is equal to the closure **`centre-global-number-of-chars`** which looks like:

          ```
          our $centre-total-number-of-chars is export = 0;
          our $centre-total-number-of-visible-chars
                                            is export = 0;

          sub centre-global-number-of-chars(
                Int:D $number-of-chars,
                Int:D $number-of-visible-chars --> Bool:D) {
              $centre-total-number-of-chars         =
                                   $number-of-chars;
              $centre-total-number-of-visible-chars =
                                   $number-of-visible-chars;
              return True;
          }

          ```

          * Which is a closure around the variables: **`$centre-total-number-of-chars`** and **`$centre-total-number-of-visible-chars`**, these are global **`our`** variables that **`Gzz::Text::Utils`** exports. But you can just use **`my`** variables from with a scope, just as well. And make the **`sub`** local to the same scope.

            [Top of Document](#table-of-contents)

            i.e.

            ```
            sub Sprintf(Str:D $format-str,
                            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                                                    Str:D :$ellipsis = '', *@args --> Str) is export {
                ...
                ...
                ...
                my Int:D $total-number-of-chars = 0;
                my Int:D $total-number-of-visible-chars = 0;
                sub internal-number-of-chars(Int:D $number-of-chars, Int:D $number-of-visible-chars --> Bool:D) {
                    $total-number-of-chars += $number-of-chars;
                    $total-number-of-visible-chars += $number-of-visible-chars;
                    return True;
                } # sub internal-number-of-chars(Int:D $number-of-chars, Int:D $number-of-visible-chars --> Bool:D) #
                ...
                ...
                ...
                for @format-str -> %elt {
                    my Str:D $type = %elt«type»;
                    if $type eq 'literal' {
                        my Str:D $lit = %elt«val»;
                        $total-number-of-chars += $lit.chars;
                        $total-number-of-visible-chars += strip-ansi($lit).chars;
                        $result ~= $lit;
                    } elsif $type eq 'fmt-spec' {
                        ...
                        ...
                        ...
                        given $spec-char {
                            when 'c' {
                                         $arg .=Str;
                                         $ref .=Str;
                                         BadArg.new(:msg("arg should be one codepoint: {$arg.codes} found")).throw if $arg.codes != 1;
                                         $max-width = max($max-width, $precision, 0) if $max-width > 0; #`« should not really have a both for this
                                                                                so munge together.
                                                                                Traditionally sprintf etc treat precision
                                                                                as max-width for strings. »
                                         if $padding eq '' {
                                             if $justify eq '' {
                                                 $result ~=  right($arg, $width, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             } elsif $justify eq '-' {
                                                 $result ~=  left($arg, $width, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             } elsif $justify eq '^' {
                                                 $result ~=  centre($arg, $width, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             }
                                         } else {
                                             if $justify eq '' {
                                                 $result ~=  right($arg, $width, $padding, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             } elsif $justify eq '-' {
                                                 $result ~=  left($arg, $width, $padding, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             } elsif $justify eq '^' {
                                                 $result ~=  centre($arg, $width, $padding, :$ref, :number-of-chars(&internal-number-of-chars), :$max-width);
                                             }
                                         }
                                     }
                            when 's' {
                                        ...
                                        ...
                                        ...
                    ...
                    ...
                    ...
                ...
                ...
                ...
                return $result;
                KEEP {
                    &number-of-chars($total-number-of-chars, $total-number-of-visible-chars);
                }
            } #`««« sub Sprintf(Str:D $format-str,
                            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                                                    Str:D :$ellipsis = '', *@args --> Str) is export »»»

            ```
      * The parameter **`:$ref`** is by default set to the value of **`strip-ansi($text)`**

        * This is used to obtain the length of the of the text using ***`wcswidth(Str)`*** from module **"`Terminal::WCWidth`"** which is used to obtain the width the text if printed on the current terminal:

          * **NB: `wcswidth` will return -1 if you pass it text with colours etc embedded in them**.
          * **"`Terminal::WCWidth`"** is witten by **bluebear94** [github:bluebear94](https://raku.land/github:bluebear94) get it with **zef** or whatever
      * **`:$max-width`** sets the maximum width of the field but if set to **`0`** (The default), will effectively be infinite (∞).
      * **`:$ellipsis`** is used to elide the text if it's too big I recommend either **`''`** the default or **`'…'`**.

[Top of Document](#table-of-contents)

### left

* ⋄

  * Left Justifying text.

    ```
    sub left(Str:D $text, Int:D $width is copy, Str:D $fill = ' ',
            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &left-global-number-of-chars,
                        Str:D :$ref = strip-ansi($text), Int:D :$max-width = 0,
                                            Str:D :$ellipsis = '' --> Str) is export

    ```

    * **`left`** is the same except that except that it puts all the padding on the right of the field.

[Top of Document](#table-of-contents)

### right

* ⋄

  * Right justifying text.

    ```
    sub right(Str:D $text, Int:D $width is copy, Str:D $fill = ' ',
              :&number-of-chars:(Int:D, Int:D --> Bool:D) = &right-global-number-of-chars,
                        Str:D :$ref = strip-ansi($text), Int:D :$max-width = 0,
                                                 Str:D :$ellipsis = '' --> Str) is export

    ```

    * **`right`** is again the same except it puts all the padding on the left and the text to the right.
    * [Top of Document](#table-of-contents)

      #### crop-field
  * text

    * Cropping Text in a field.

      ```
      sub crop-field(Str:D $text,
                     Int:D $w is rw,
                     Int:D $width is rw,
                     Bool:D $cropped is rw,
                     Int:D $max-width,
                     Str:D :$ellipsis = '' --> Str:D) is export {

      ```

      * **`crop-field`** used by **`centre`**, **`left`** and **`right`** to crop their input if necessary. Copes with ANSI escape codes.

        * **Where**

          * **`$text`** is the text to be cropped possibly, wit ANSI escapes embedded.
          * **`$w`** is used to hold the width of **`$text`** is read-write so will return that value.
          * **`$width`** is the desired width. Will be used to return the updated width.
          * **`$cropped`** is used to return the status of whether or not **`$text`** was truncated.
          * **`$max-width`** is the maximum width we are allowing.
          * **`$ellipsis`** is used to supply a eliding . Empty string by default.

[Top of Document](#table-of-contents)

## Sprintf

* Sprintf like sprintf only it can deal with ANSI highlighted text. And has lots of other options, including the ability to specify a **`$max-width`** using **`width.precision.max-width`**, which can be **`.*`**, **`*<num>$`**, **`.*`**, or **`<num>`**

  ```
  sub Sprintf(Str:D $format-str,
             :&number-of-chars:(Int:D, Int:D --> Bool:D) =
                                               &Sprintf-global-number-of-chars,
                                               Str:D :$ellipsis = '',
                                               *@args --> Str) is export

  ```

  * Where:

    * **`format-str`** is is a superset of the **`sprintf`** format string, but it has extra features: like the flag **`[ <char> ]`** where can be almost anything except **`[`**, **`]`** **control characters**, **white space other than the normal space**, and **`max-width`** after the precision.

      * The format string looks like this:

        ```
        token format      { <chunks>+ }
        token chunks      { [ <chunk> || '%' <format-spec> ] }
        token chunk       { <-[%]>+ }
        token format-spec { [ <fmt-esc> || <fmt-spec> ] }
        token fmt-esc     { [      '%' #`« a literal % »
                                || 'N' #`« a nl i.e. \n char but does not require interpolation so no double quotes required »
                                || 'T' #`« a tab i.e. \t char but does not require interpolation so no double quotes required »
                                || 'n' #`« not implemented and will not be, throws an exception if matched »
                                || 't' #`« not implemented and will not be, throws an exception if matched »
                            ]
                          }
        token fmt-spec   { [ <dollar-directive> '$' ]? <flags>?  <width>? [ '.' <precision> [ '.' <max-width> ]? ]? <modifier>? <spec-char> }

        ```
      * [Top of Document](#table-of-contents)

        * Where

          * **`dollar-directive`** is a integer >= 1
          * **`flags`** is any zero or more of:

            * **`+`** put a plus in front of positive values.
            * **`-`** left justify, right is the default
            * **`^`** centre justify.
            * **`#`** ensure the leading **`0`** for any octal, prefix non-zero hexadecimal with **`0x`** or **`0X`**, prefix non-zero binary with **`0b`** or **`0B`**
            * **`v`** vector flag (used only with d directive)
            * **`' '`** pad with spaces.
            * **`0`** pad with zeros.
            * **`[ <char> ]`** pad with character char where char matches:

              * **`<-[ <cntrl> \s \[ \] ]> || ' '`** i.e. anything except control characters, white space (apart from the basic white space (i.e. \x20 or the one with ord 32)), and **`[`** and finally **`]`**.
            * [Top of Document](#table-of-contents)
          * **`width`** is either an integer or a **`*`** or a **`*`** followed by an integer >= 1 and a '$'.
          * **`precision`** is a **`.`** followed by either an positive integer or a **`*`** or a **`*`** followed by an integer >= 1 and a '$'.
          * **`max-width`** is a **`.`** followed by either an positive integer or a **`*`** or a **`*`** followed by an integer >= 1 and a '$'.
          * **`modifier`** These are not implemented but is one of:

            * **`hh`** interpret integer as a type **`char`** or **`unsigned char`**.
            * **`h`** interpret integer as a type **`short`** or **`unsigned short`**.
            * **`j`** interpret integer as a type **`intmax_t`**, only with a C99 compiler (unportable).
            * **`l`** interpret integer as a type **`long`** or **`unsigned long`**.
            * **`ll`** interpret integer as a type **`long long`**, **`unsigned long long`**, or **`quad`** (typically 64-bit integers).
            * **`q`** interpret integer as a type **`long long`**, **`unsigned long long`**, or **`quad`** (typically 64-bit integers).
            * **`L`** interpret integer as a type **`long long`**, **`unsigned long long`**, or **`quad`** (typically 64-bit integers).
            * **`t`** interpret integer as a type **`ptrdiff_t`**.
            * **`z`** interpret integer as a type **`size_t`**.
          * [Top of Document](#table-of-contents)
          * **`spec-char`** or the conversion character is one of:

            * **`c`** a character with the given codepoint.
            * **`s`** a string.
            * **`d`** a signed integer, in decimal.
            * **`u`** an unsigned integer, in decimal.
            * **`o`** an unsigned integer, in octal, with a **`0o`** prepended if the **`#`** flag is present.
            * **`x`** an unsigned integer, in hexadecimal, with a **`0x`** prepended if the **`#`** flag is present.
            * **`e`** a floating-point number, in scientific notation.
            * **`f`** a floating-point number, in fixed decimal notation.
            * **`g`** a floating-point number, in %e or %f notation.
            * **`X`** like **`x`**, but using uppercase letters, with a **`0X`** prepended if the **`#`** flag is present.
            * **`E`** like **`e`**, but using an uppercase **`E`**.
            * **`G`** like **`g`**, but with an uppercase **`E`** (if applicable).
            * **`b`** an unsigned integer, in binary, with a **`0b`** prepended if the **`#`** flag is present.
            * **`B`** an unsigned integer, in binary, with a **`0B`** prepended if the **`#`** flag is present.
            * **`i`** a synonym for **`%d`**.
            * **`D`** a synonym for **`%ld`**.
            * **`U`** a synonym for **`%lu`**.
            * **`O`** a synonym for **`%lo`**.
            * **`F`** a synonym for **`%f`**.
      * [Top of Document](#table-of-contents)
    * **`:&number-of-chars`** is an optional named argument which takes a function with a signature **`:(Int:D, Int:D --` Bool:D)**> if not specified it will have the value of **`&Sprintf-global-number-of-chars`** which is defined as:

      ```
      our $Sprintf-total-number-of-chars is export = 0;
      our $Sprintf-total-number-of-visible-chars is export = 0;

      sub Sprintf-global-number-of-chars(Int:D $number-of-chars, Int:D $number-of-visible-chars --> Bool:D) {
          $Sprintf-total-number-of-chars         = $number-of-chars;
          $Sprintf-total-number-of-visible-chars = $number-of-visible-chars;
          return True
      }

      ```

      * This is exactly the same as the argument by the same name in **`centre`**, **`left`** and **`right`** above.

        i.e.

        ```
        sub test( --> True) is export {
            ...
            ...
            ...
            my $test-number-of-chars = 0;
            my $test-number-of-visible-chars = 0;

            sub test-number-of-chars(Int:D $number-of-chars, Int:D $number-of-visible-chars --> Bool:D) {
                $test-number-of-chars         = $number-of-chars;
                $test-number-of-visible-chars = $number-of-visible-chars;
                return True
            }

            put Sprintf('%30.14.14s, %30.14.13s%N%%%N%^*.*s%3$*4$.*3$.*6$d%N%2$^[&]*3$.*4$.*6$s%T%1$[*]^100.*4$.99s',
                                                ${ arg => $highlighted, ref => $text }, $text, 30, 14, $highlighted, 13,
                                                                            :number-of-chars(&test-number-of-chars), :ellipsis('…'));
            dd $test-number-of-chars,  $test-number-of-visible-chars;
            put Sprintf('%30.14.14s,  testing %30.14.13s%N%%%N%^*.*s%3$*4$.*3$.*6$d%N%2$^[&]*3$.*4$.*6$s%T%1$[*]^100.*4$.99s',
                                        $[ $highlighted, $text ], $text, 30, 14, $highlighted, 13, 13,
                                                                            :number-of-chars(&test-number-of-chars), :ellipsis('…'));
            dd $test-number-of-chars,  $test-number-of-visible-chars;
            ...
            ...
            ...
        }

        ```

        * **Note: This is a closure we should always use a closure if we want to get the number of characters printed.**
      * [Top of Document](#table-of-contents)
    * **`:$ellipsis`** this is an optional argument of type **`Str:D`** which defaults to **`''`**, if set will be used to mark elided text, if the argument is truncated due to exceeding the value of **`max-width`** (note **`max-width`** defaults to **`0`** which means infinity). The recommended value would be something like **`…`**.
    * **`*@args`** is an arbitrary long list of values each argument can be either a scalar value to be printed or a Hash or an Array

      * If a Hash then it should contain two pairs with keys: **`arg`** and **`ref`**; denoting the actual argument and a reference argument respectively, the ref argument should be the same as **`arg`** but with no ANSI formatting etc to mess up the counting. As this ruins formatting spacing. If not present will be set to **`strip-ansi($arg)`**, only bother with all this if **`strip-ansi($arg)`** isn't good enough.
      * If a Array then it should contain two values. The first being **`arg`** and the other being **`ref`**; everything else is the same as above.
      * **`arg`** the actual argument.
      * **`@args[$i][]`** the actual argument. Where **`$i`** is the current index into the array of args.
      * **`@args[$i][1]`** the reference argument, as in the **`:$ref`** arg of the **left**, **right** and **centre** functions which it uses. It only makes sense if your talking strings possibly formatted if not present will be set to **`strip-ansi($arg)`** if $arg is a Str or just $arg otherwise.
      * If it's a scalar then it's the argument itself. And **`$ref`** is **`strip-ansi($arg)`** if $arg is a string type i.e. Str or just **C**$arg>> otherwise.

        * **`ref`** the reference argument, as in the **`:$ref`** arg of the **left**, **right** and **centre** functions which it uses. It only makes sense if your talking strings possibly formatted if not present will be set to **`strip-ansi($arg)`** if $arg is a Str or just $arg otherwise.

          i.e.

          ```
          put Sprintf('%30.14.14s, %30.14.13s%N%%%N%^*.*s%3$*4$.*3$.*6$d%N%2$^[&]*3$.*4$.*6$s%T%1$[*]^100.*4$.99s',
                                      ${ arg => $highlighted, ref => $text }, $text, 30, 14, $highlighted, 13,
                                                                                :number-of-chars(&test-number-of-chars), :ellipsis('…'));
          dd $test-number-of-chars,  $test-number-of-visible-chars;
          put Sprintf('%30.14.14s,  testing %30.14.13s%N%%%N%^*.*s%3$*4$.*3$.*6$d%N%2$^[&]*3$.*4$.*6$s%T%1$[*]^100.*4$.99s',
                                      $[ $highlighted, $text ], $text, 30, 14, $highlighted, 13, 13,
                                                                                :number-of-chars(&test-number-of-chars), :ellipsis('…'));
          dd $test-number-of-chars,  $test-number-of-visible-chars;

          ```

[Top of Document](#table-of-contents)

## Printf

* Same as **`Sprintf`** but writes it's output to **`$*OUT`** or an arbitrary filehandle if you choose.

  * defined as

    ```
    multi sub Printf(Str:D $format-str,
            :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                          Str:D :$ellipsis = '', *@args --> True) is export {
        Sprintf($format-str, :&number-of-chars, :$ellipsis, |@args).print;
    } #`««« sub Printf(Str:D $format-str,
             :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                          Str:D :$ellipsis = '', *@args --> True) is export »»»

    multi sub Printf(IO::Handle:D $fp, Str:D $format-str,
             :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                          Str:D :$ellipsis = '', *@args --> True) is export {
        $fp.print: Sprintf($format-str, :&number-of-chars, :$ellipsis, |@args);
    } #`««« sub Printf(my IO::Handle:D $fp, Str:D $format-str,
             :&number-of-chars:(Int:D, Int:D --> Bool:D) = &Sprintf-global-number-of-chars,
                                          Str:D :$ellipsis = '', *@args --> True) is export »»»

    ```

[Top of Document](#table-of-contents)

### MultiT

A lot of types but not Any.

```
subset MultiT is export of Any where * ~~  Str | Int | Rat | Num | Bool | Array;

```

### menu

Display a text based menu.

```
sub menu(@candidates is copy, Str:D $message = "",
                              :&row:(Int:D $c, Int:D $p, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$highlight-bg-colour = '',
                                     Str:D :$highlight-fg-colour = '',
                                     Str:D :$bg-colour0 = '',
                                     Str:D :$fg-colour0 = '',
                                     Str:D :$bg-colour1 = '',
                                     Str:D :$fg-colour1 = '' --> Str:D) = &default-row,
                              :&value:(Int:D $c, @a --> MultiT) = &default-value,
                              Bool:D :c(:color(:$colour)) is copy = False,
                              Bool:D :s(:$syntax) = False,
                              Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold,
                              Str:D :$highlight-fg-colour = t.bright-yellow,
                              Str:D :$bg-colour0 = t.bg-yellow ~ t.bold,
                              Str:D :$fg-colour0 = t.bright-blue,
                              Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold,
                              Str:D :$fg-colour1 = t.bright-blue,
                              Str:D :$bg-prompt = t.bg-green ~ t.bold,
                              Str:D :$fg-prompt = t.bright-blue,
                              Bool:D :$wrap-around = False --> MultiT) is export

```

* Where:

  * **`@candidates`** is an array of hashes to make up the rows of the menu.
  * **`$message`** is a message to be displayed at the top of the ascii text form of things (i.e. no colourising).
  * **`&row`** is is a callback to deal with the rows of the menu.

    * Where

      * **`$c`** is the current row count.
      * **`$p`** is the current position in the @candidates array.
      * **`@a`** is the array @candidates itself.
      * **`$highlight-bg-colour`** is the background colour of the current row (i.e. $c == $p).
      * **`$highlight-fg-colour`** is the foreground colour of the current row (i.e. $c == $p).
      * **`$bg-colour0`** is the background colour of the row (i.e. $c %% 2).
      * **`$fg-colour0`** is the foreground colour of the row (i.e. $c %% 2).
      * **`$bg-colour1`** is the background colour of the row (i.e. $c % 2 != 0 or not $c %% 2).
      * **`$fg-colour1`** is the foreground colour of the row (i.e. $c % 2 != 0).
  * **`&value`** is a callback to get the return value for the function.

    * **`$c`** is the row selected.
    * **`$c`** is the array @candidates.
  * **`:c(:color(:$colour))`** defines a boolean flag to


## dist_zef-grizzlysmit-Gzz-Text-Utils.md
## Chunk 2 of 2
 tell whether to use colours or not.

    * you can use **`:c`**, **`:color`** or **`:colour`** for this they are all exactly the same.
  * **`:s(:$syntax)`** same as **`$colour`** except it could result in some sort of syntax highlighting.
  * **`$highlight-bg-colour`** the background colour to use to highlight the current line.
  * **`$highlight-fg-colour`** the foreground colour to use to highlight the current line.
  * **`$bg-colour0`** the background colour to use if the line count is divisible by 2.
  * **`$fg-colour0`** the foreground colour to use if the line count is divisible by 2.
  * **`$bg-colour1`** the background colour to use if the line count is not divisible by 2.
  * **`$fg-colour1`** the foreground colour to use if the line count is not divisible by 2.
  * **`$bg-prompt`** the background colour to use on the prompt line below the selection area.
  * **`$fg-prompt`** the foreground colour to use on the prompt line below the selection area.
  * **`$wrap-around`** if true then the selection area wraps around, (i.e going past the end wraps around, instead of refusing to go there).

    * **`$highlight-bg-colour`** to **`$wrap-around`** are all just used for the dropdown case (i.e. **`$colour`** or **`$syntax`** are True)
    * **`$syntax`** is no different from **`$colour`** unless the user defines it using the **`:&row`** parameter.

      * calls [dropdown](#dropdown) to do the colour work.

[Top of Document](#table-of-contents)

### input-menu(…)

```
sub input-menu(@candidates is copy, Str:D $message = "",
                              :&row:(Int:D $c, Int:D $p, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$highlight-bg-colour = '', Str:D :$highlight-fg-colour = '',
                                     Str:D :$bg-colour0 = '', Str:D :$fg-colour0 = '',
                                     Str:D :$bg-colour1 = '', Str:D :$fg-colour1 = '' --> Str:D) = &default-row-input-menu,
                              :&value:(Int:D $c, @a --> MultiT) = &default-value,
                              :&elt-prompt:(Int:D $c, @a,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$bg-prompt = '', Str:D :$fg-prompt = '' --> Str:D)  = &default-prompt,
                              :&edit:(Int:D $c, @a is copy, Str:D $e --> Bool:D) = &default-edit,
                              Bool:D :c(:color(:$colour)) is copy = False,
                              Bool:D :s(:$syntax) = False,
                              Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold,
                              Str:D :$highlight-fg-colour = t.bright-yellow,
                              Str:D :$bg-colour0 = t.bg-yellow ~ t.bold,
                              Str:D :$fg-colour0 = t.bright-blue,
                              Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold,
                              Str:D :$fg-colour1 = t.bright-blue,
                              Str:D :$bg-prompt = t.bg-green ~ t.bold,
                              Str:D :$fg-prompt = t.bright-blue,
                              Bool:D :$wrap-around = False --> MultiT) is export

```

* Where:

  * **`@candidates`** is an array of hashes to make up the rows of the menu.
  * **`$message`** is a message to be displayed at the top of the ascii text form of things (i.e. no colourising).
  * **`&row`** is is a callback to deal with the rows of the menu.

    * Where

      * **`$c`** is the current row count.
      * **`$p`** is the current position in the @candidates array.
      * **`@a`** is the array @candidates itself.
      * **`$highlight-bg-colour`** is the background colour of the current row (i.e. $c == $p).
      * **`$highlight-fg-colour`** is the foreground colour of the current row (i.e. $c == $p).
      * **`$bg-colour0`** is the background colour of the row (i.e. $c %% 2).
      * **`$fg-colour0`** is the foreground colour of the row (i.e. $c %% 2).
      * **`$bg-colour1`** is the background colour of the row (i.e. $c % 2 != 0 or not $c %% 2).
      * **`$fg-colour1`** is the foreground colour of the row (i.e. $c % 2 != 0).
  * **`&value`** is a callback to get the return value for the function.

    * **`$c`** is the row selected.
    * **`$c`** is the array @candidates.
  * **`&elt-prompt:(Int:D $c, @a, Bool:D :$colour = False, Bool:D :$syntax = False, Str:D :$bg-prompt = '', Str:D :$fg-prompt = '' --> Str:D) = &default-prompt`**

    The callback called by the function to get the prompts to let the user edit the value of the row.

    * **`$c`** is the entry choosen by the user.
    * **`@a`** is the candidates array.
    * **`:c(:color(:$colour))`** defines a boolean flag to tell whether to use colours or not.

      * you can use **`:c`**, **`:color`** or **`:colour`** for this they are all exactly the same.
    * **`:s(:$syntax)`** same as **`$colour`** except it could result in some sort of syntax highlighting.
    * **`$bg-prompt`** the background colour to use on the prompt line below the selection area.
    * **`$fg-prompt`** the foreground colour to use on the prompt line below the selection area.
  * **`&edit:(Int:D $c, @a is copy, Str:D $e --> Bool:D) = &default-edit`**

    The callback called by the function to set the new value of the row.

    * **`$c`** is the entry choosen by the user.
    * **`@a`** is the candidates array.
  * **`:c(:color(:$colour))`** defines a boolean flag to tell whether to use colours or not.

    * you can use **`:c`**, **`:color`** or **`:colour`** for this they are all exactly the same.
  * **`:s(:$syntax)`** same as **`$colour`** except it could result in some sort of syntax highlighting.
  * **`$highlight-bg-colour`** the background colour to use to highlight the current line.
  * **`$highlight-fg-colour`** the foreground colour to use to highlight the current line.
  * **`$bg-colour0`** the background colour to use if the line count is divisible by 2.
  * **`$fg-colour0`** the foreground colour to use if the line count is divisible by 2.
  * **`$bg-colour1`** the background colour to use if the line count is not divisible by 2.
  * **`$fg-colour1`** the foreground colour to use if the line count is not divisible by 2.
  * **`$bg-prompt`** the background colour to use on the prompt line below the selection area.
  * **`$fg-prompt`** the foreground colour to use on the prompt line below the selection area.
  * **`$wrap-around`** if true then the selection area wraps around, (i.e going past the end wraps around, instead of refusing to go there).

    * **`$highlight-bg-colour`** to **`$wrap-around`** are all just used for the dropdown case (i.e. **`$colour`** or **`$syntax`** are True)
    * **`$syntax`** is no different from **`$colour`** unless the user defines it using the **`:&row`** parameter.

      * calls [dropdown](#dropdown) to do the colour work.
      * **NB: the colours stuff is not yet implemented**

[Top of Document](#table-of-contents)

### dropdown(…)

A text based dropdown/list or menu with ANSI colours.

```
sub dropdown(MultiT:D $id, Int:D $window-height is copy, Str:D $id-name,
                        &setup-option-str:(Int:D $c, Int:D $p, @a --> Str:D),
                        &find-pos:(MultiT $r, Int:D $p, @a --> Int:D),
                        &get-result:(MultiT:D $res, Int:D $p, Int:D $l, @a --> MultiT:D),
                        @array,
                        Str:D :$highlight-bg-colour = t.bg-color(0, 0, 127) ~ t.bold,
                        Str:D :$highlight-fg-colour = t.bright-yellow,
                        Str:D :$bg-colour0 = t.bg-yellow ~ t.bold,
                        Str:D :$fg-colour0 = t.bright-blue,
                        Str:D :$bg-colour1 = t.bg-color(0, 127, 0) ~ t.bold,
                        Str:D :$fg-colour1 = t.bright-blue,
                        Str:D :$bg-prompt = t.bg-green ~ t.bold,
                        Str:D :$fg-prompt = t.bright-blue,
                        Bool:D :$wrap-around = False --> MultiT) is export

```

* Where

  * **`$id`** is the starting value of our position in the array/choices.
  * **`$window-height`** is the number of rows of characters to display at a time.
  * **`$id-name`** is the name of the parameter we are scrolling.
  * **`&setup-option-str`** is a function that returns the current row.

    * Where:

      * the arg **`$c`** will be the count of the row we are drawing.
      * the arg **`$p`** will be the position in the array we are at.
      * the arg **`@a`** will be the **`@array`** supplied to **`dropdown(…)`**

        * the use of a function for this means you can compute a much more complex field.
  * **`&find-pos`** is a function that finds the start position in the **`dropdown`**.

    * Where:

      * the arg **`$r`** is the value in the array **`@array`** to look for.
      * the arg **`$p`** is the best approximation of where it might be if you are using it in a loop or something it could be where it last was.
      * the arg **`@a`** the argument **`@array`** that was passed to **`dropdown`**.

        * you can name these argument anything you like in you function, and because of the computed nature of this function and the other two you have great flexibility.
  * **`&get-result`** is a function to work out the value selected.

    * Where:

      * the arg **`$res`** is the default value to return.
      * the arg **`$p`** is the current position in the array **`@array`** supplied to **`dropdown`**.
      * the arg **`$l`** is the length of the array **`@array`**.
      * the arg **`@a`** is the array **`@array`** that was supplied to **`dropdown`**.
  * **`@array`** the array of rows to display.
  * **`$highlight-bg-colour`** the background colour to use to highlight the current line.
  * **`$highlight-fg-colour`** the foreground colour to use to highlight the current line.
  * **`$bg-colour0`** the background colour to use if the line count is divisible by 2.
  * **`$fg-colour0`** the foreground colour to use if the line count is divisible by 2.
  * **`$bg-colour1`** the background colour to use if the line count is not divisible by 2.
  * **`$fg-colour1`** the foreground colour to use if the line count is not divisible by 2.
  * **`$bg-prompt`** the background colour to use on the prompt line below the selection area.
  * **`$fg-prompt`** the foreground colour to use on the prompt line below the selection area.
  * **`$wrap-around`** if true then the selection area wraps around, (i.e going past the end wraps around, instead of refusing to go there).

    * Because we use a function we can compute much more complex results; depending on what we have in **`@array`**. The result can be any of Str, Int, Rat or Num see [MultiT](#multit).

Here is an example of use.

[Top of Document](#table-of-contents)

```
my &setup-option-str = sub (Int:D $cnt, Int:D $p, @array --> Str:D ) {
    my Str $name;
    my Str $cc;
    my Str $flag;
    my Str $prefix;
    if $cnt < 0 {
        $name   = "No country selected yet.";
        $cc     = "";
        $flag   = "";
        $prefix = "you must choose one";
    } else {
        my %row = @array[$cnt];
        $name   = %row«_name»;
        $cc     = %row«cc»;
        try {
            CATCH {
                default {
                    my $Name = $name;
                    $Name ~~ s:g/ <wb> 'and' <wb> /\&/;
                    try {
                        CATCH {
                            default { $flag = uniparse 'PENGUIN'}
                        }
                        $flag = uniparse $Name;
                    }
                }
            }
            $flag   = uniparse $name;
        }
        $prefix = %row«prefix»;
    }
    return "$flag $name: $cc ($prefix)"
};
my &find-pos = sub (MultiT $result, Int:D $pos, @array --> Int:D) {
    for @array.kv -> $idx, %r {
        if %r{$id-name} == $result {
            $pos = $idx;
            last; # found so don't waste resources #
        }
    }
    return $pos;
}
my &get-result = sub (MultiT:D $result, Int:D $pos, Int:D $length, @array --> MultiT:D ) {
    my $res = $result;
    if $pos ~~ 0..^$length {
      my %row = |%(@array[$pos]);
      $res = %row«id» if %row«id»:exists;
    }
    return $res
};
my Int:D $cc-id        = dropdown($cc_id, 20, 'id',
                                    &setup-option-str, &find-pos, &get-result, @_country);
while !valid-country-cc-id($cc-id, %countries) {
    $cc-id             = dropdown($cc-id, 20, 'id',
                                    &setup-option-str, &find-pos, &get-result, @_country);
}

```

Or using a much simpler array. **NB: from `menu`**

[Top of Document](#table-of-contents)

```
my &setup-option-str = sub (Int:D $cnt, Int:D $pos, @array --> Str:D ) {
    return @array[$cnt];
};
my &get-result = sub (MultiT:D $result, Int:D $pos, Int:D $length, @array --> MultiT:D ) {
    my $res = $result;
    if $pos ~~ 0..^$length {
      $res = @array[$pos];
    }
    return $res
};
my &find-pos = sub (MultiT $result, Int:D $pos, @array --> Int:D) {
    for @array.kv -> $idx, $r {
        if $r eq $result {
            $pos = $idx;
            last; # found so don't waste resources #
        }
    }
    return $pos;
}
my Str:D $result = dropdown(@candidates[@candidates.elems - 1], 40, 'backup',
                                    &setup-option-str, &find-pos, &get-result, @candidates);

```

[Top of Document](#table-of-contents)

### lead-dots(…)

Returns **`$text`** in a field of **`$width`** with a line of dots preceding it. Sort of like **`left`** with **`$fill`** defaulting to **`.`** but with a single space between the text and the padding.

```
sub lead-dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

```

* Where:

  * **`$text`** the text to be preceded by the dots.
  * **`$width`** the width of the total field.
  * **`$fill`** the fill char or string.

[Top of Document](#table-of-contents)

### trailing-dots(…)

Returns **`$text`** in a field of **`$width`** with a line of dots trailing after it. Sort of like **`right`** with **`$fill`** defaulting to **`.`** but with a single space between the text and the padding.

```
sub trailing-dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

```

* Where:

  * **`$text`** the text to be trailed by the dots.
  * **`$width`** the width of the total field.
  * **`$fill`** the fill char or string.

[Top of Document](#table-of-contents)

### dots(…)

Returns **`$text`** in a field of **`$width`** with a line of dots preceding it. Sort of like **`left`** with **`$fill`** defaulting to **`.`**.

```
sub dots(Str:D $text, Int:D $width is copy, Str:D $fill = '.' --> Str) is export

```

* Where:

  * **`$text`** the text to be preceded by the dots.
  * **`$width`** the width of the total field.
  * **`$fill`** the fill char or string.

[Top of Document](#table-of-contents)


## dist_zef-tbrowder-DateTime-Posix.md
[![Actions Status](https://github.com/tbrowder/DateTime-Posix/actions/workflows/linux.yml/badge.svg)](https://github.com/tbrowder/DateTime-Posix/actions) [![Actions Status](https://github.com/tbrowder/DateTime-Posix/actions/workflows/macos.yml/badge.svg)](https://github.com/tbrowder/DateTime-Posix/actions) [![Actions Status](https://github.com/tbrowder/DateTime-Posix/actions/workflows/windows.yml/badge.svg)](https://github.com/tbrowder/DateTime-Posix/actions)

# NAME

**DateTime::Posix** - Provides a DateTime object that returns posix values with fractional seconds

Note this module's routines have been incorporated into core Raku version **6.e**.

# SYNOPSIS

```
use DateTimePosixReal;
my $dt = DateTime::Posix.new: '1970-01-01T00:00:00.23Z';
say $dt.Posix;      # OUTPUT: «0.23␤»
say $dt.posix-real; # OUTPUT: «0.23␤»

```

# DESCRIPTION

**DateTime::Posix** is a child class of Raku's **DateTime** class that returns 'posix' values as fractional instead of integral seconds.

The module has two methods with slightly different names to allow some user flexibility:

```
method Posix($in-timezone? --> Real:D) {...}

```

and

```
method posix-real($in-timezone? --> Real:D) {...}

```

This module will be deprecated when Raku version **6.e** is released since that version will provide the same capability for the **DateTime** base class as its 'posix' method will then return fractional rather than integral seconds.

# AUTHOR

Tom Browder ([tbrowder@acm.org](mailto:tbrowder@acm.org))

# COPYRIGHT and LICENSE

Copyright © 2021-2023 Tom Browder

This library is free software; you may redistribute or modify it under the Artistic License 2.0.


## dist_zef-tony-o-DB-Xoos-Pg.md
# DB::Xoos::Pg

DB::Xoos::Pg is an ORM designed for convenience and ease of use. It is based upon [DB::Xoos](https://github.com/tony-o/p6-xoo), provides roles and enhancements and allows you to connect to postgres for ultimate magic.

[![CircleCI](https://circleci.com/gh/tony-o/p6-db-xoos-pg.svg?style=svg)](https://circleci.com/gh/tony-o/p6-db-xoos-pg)

# Usage

Below is a minimum viable model setup for your app. Xoos does *not* create the table for you, that is up to you.

## autoloading models (only available in Pg at the moment)

### lib/app.pm6

```
use DB::Xoos::Pg;

my DB::Xoos::Pg $d .=new;

$d.connect('pg://xyyz/example', options => { :dynamic-loading });

my $customer-model = $d.model('Customer');
my $new-customer   = $customer-model.new-row;
$new-customer.name('xyz co');
$new-customer.rate(150);
$new-customer.update; # runs an insert because this is a new row

my $xyz = $customer-model.search({ name => { 'like' => '%xyz%' } }).first;
$xyz.rate( $xyz.rate * 2 ); #twice the rate!
$xyz.update; # UPDATEs the database

my $xyz-orders = $xyz.orders.count;

```

## same example with model modules

### lib/app.pm6

```
use DB::Xoos::Pg;

my DB::Xoos::Pg $d .=new;

$d.connect('sqlite://xyz.sqlite3');

my $customer-model = $d.model('Customer');
my $new-customer   = $customer-model.new-row;
$new-customer.name('xyz co');
$new-customer.rate(150);
$new-customer.update; # runs an insert because this is a new row

my $xyz = $customer-model.search({ name => { 'like' => '%xyz%' } }).first;
$xyz.rate( $xyz.rate * 2 ); #twice the rate!
$xyz.update; # UPDATEs the database

my $xyz-orders = $xyz.orders.count;

```

### lib/Model/Customer.pm6

```
use DB::Xoos::Role::Model;
unit class Model::Customer does DB::Xoos::Role::Model['customer'];

has @.columns = [
  id => {
    type           => 'integer',
    nullable       => False,
    is-primary-key => True,
    auto-increment => 1,
  },
  name => {
    type           => 'text',
  },
  rate => {
    type => 'integer',
  },
];

has @.relations = [
  orders => { :has-many, :model<Order>, :relate(id => 'customer_id') },
];

```

# role DB::Xoos::Role::Model

What is a model? A model is essentially a table in your database. Your ::Model::X is pretty barebones, in this module you'll defined `@.columns` and `@.relations` (if there are any relations).

## Example

```
use DB::Xoos::Role::Model;
# the second argument below is optional and also accepts a type.
# if the arg is omitted then it attempts to auto load ::Row::Customer
# if it fails to auto load then it uses an anonymous Row and adds convenience methods to that
unit class X::Model::Customer does DB::Xoos::Role::Model['customer', 'X::Row::Customer'];

has @.columns = [
  id => {
    type           => 'integer',
    nullable       => False,
    is-primary-key => True,
    auto-increment => 1,
  },
  name => {
    type           => 'text',
  },
  contact => {
    type => 'text',
  },
  country => {
    type => 'text',
  },
];

has @.relations = [
  orders => { :has-many, :model<Order>, :relate(id => 'customer_id') },
  open_orders => { :has-many, :model<Order>, :relate(id => 'customer_id', '+status' => 'open') },
  completed_orders => { :has-many, :model<Order>, :relate(id => 'customer_id', '+status' => 'closed') },
];

# down here you can have convenience methods

method delete-all { #never do this in real life
  die '.delete-all disabled in prod or if %*ENV{in-prod} not defined'
    if !defined %*ENV{in-prod} || so %*ENV{in-prod};
  my $s = self.search({ id => { '>' => -1 } });
  $s.delete;
  !so $s.count;
}

```

In this example we're creating a customer model with columns `id, name, contact, country` and relations with specific filter criteria. You may notice the `+status => 'open'` on the open\_orders relationship, the `+` here indicates it's a filter on the original table.

### Breakdown

`class :: does DB::Xoos::Role::Model['table-name', 'Optional String or Type'];`

Here you can see the role accepts one or two parameters, the first is the DB table name, the latter is a String or Type of the row you'd like to use for this model. If no row is found then Xoos will create a generic row and add helper methods for you using the model's column data.

`@.columns`

A list of columns in the table. It is highly recommended you have *one* `is-primary-key` or `.update` will have unexpected results.

`@.relations`

This accepts a list of key values, the key defining the accessor name, the later a hash describing the relationship. `:has-one` and `:has-many` are both used to dictate whether a Xoos model returns an inflated object (:has-one) or a filterable object (:has-many).

## Methods

### `search(%filter?, %options?)`

Creates a new filterable model and returns that. Every subsequent call to `.search` will *add* to the existing filters and options the best it can.

Example:

```
my $customer = $dbo.model('Customer').search({
  name => { like => '%bozo%' },
}, {
  order-by => [ created_date => 'DESC', 'customer_name' ],
});
# later on ...
my $geo-filtered-customers = $customer.search({ country => 'usa' });
# $geo-filtered-customers effective filter is:
#   {
#      name => { like => '%bozo%' },
#      country => 'usa',
#   }

```

### `.all(%filter?)`

Returns all rows from query (an array of inflated `::Row::XYZ`). Providing `%filter` is the same as doing `.search(%filter).all` and is provided only for convenience.

### `.first(%filter?, :$next = False)`

Returns the first row (again, inflated `::Row::XYZ`) and caches the prepared statement (this is destroyed and ignored if $next is falsey)

### `.next(%filter?)`

Same as calling `.first(%filter, :next)`

### `.count(%filter?)`

Returns the result of a `select count` for the current filter selection. Providing `%filter` results in `.search(%filter).count`

### `.delete(%filter?)`

Deletes all rows matching criteria. Providing `%filter` results in `.search(%filter).delete`

### `.insert(%field-data?)`

Creates a new row with %field-data.

## Convenience methods

DB::Xoos::Role::Model inheritance allows you to have convenience methods, these methods can act on whatever the current set of filters is.

Consider the following:

Convenience model definition:

```
class X::Model::Customer does DB::Xoos::Role::Model['customer'];

# columns and relations

method remove-closed-orders {
  self.closed_orders.delete;
}

```

Later in your code:

```
my $customers = $dbo.model('Customer');

my $all-customers    = $customers.search({ id => { '>' => -1 } });
my $single-customers = $customers.search({ id => 5 });

$all-customers.remove-closed-orders;
# this removes all orders for customers with an id > -1
$single-customer.remove-closed-orders;
# this removes all orders for customers with id = 5

```

# role DB::Xoos::Role::Row

A role to apply to your `::Row::Customer`. If there is no `::Row::Customer` a generic row is created using the column and relationship data specified in the corresponding `Model` and this file is only really necessary if you want to add convenience methods.

When a `class :: does DB::Xoos::Role::Row`, it receives the info from the model and adds the methods for setting/getting field data.

With the model definition above:

```
my $invoice-model = $dbo.model('invoice');
my $invoice = $invoice-model.new-row({
  customer_id => $customer.id,
  amount      => 400,
});  # this $invoice is NOT in the database until .update

my $old-amount = $invoice.amount; # = 400
$invoice.amount($invoice.amount * 2);
my $new-amount = $invoice.amount; # = 800

$invoice.update;

```

If there is a collision in the naming conventions between your model and the row then you'll need to use `[set|get]-column`

## Methods

### `.duplicate`

Duplicates the row omitting the `is-primary-key` field so the subsequent `.save` results in a new row rather than updating

### `.as-hash`

Returns the current field data for the row as a hash. If there has been unsaved updates to fields then it returns *those* values instead of what is in the database. You can determine whether the row has field-changes with `is-dirty`

### `.set-column(Str $key, $value)`

Updates the field data for the column (not stored in database until `.update` is called). If you want to `.wrap` a field setter for a certain key, wrap this and filter for the key

### `.get-column(Str $key)`

Retrieves the value for `$key` with any field changes having priority over data in database, use `.is-dirty`

### `.get-relation(Str $column, :%spec?)`

It is recommended any Model with a relationship name that conflicts and causes no convenience method to be generated be renamed, but use this if you must. `$customer.orders` is calling essentially `$customer.get-relation('orders')`. Do not provide `%spec` unless you know what you're doing.

### `.update`

Saves the row in the database. If the field with a positive `is-primary-key` is *set* then it runs and `UPDATE ...` statement, otherwise it `INSERT ...`s and updates the Row's `is-primary-key` field. Ensure you set one field with `is-primary-key`

## Field validation

It's just this easy:

```
has @.columns = [
  qw<...>,
  phone => {
    type     => 'text',
    validate => sub ($new-value) {
      # return Falsey value here for validation to fail
      #   Truthy value will cause validation to succeed
    },
  },
  qw<...>,
];

```


## dist_zef-dwarring-Text-FriBidi.md
## Name

Text::FriBidi

## Synopsis

### Single line reordering

```
use Text::FriBidi::Line;
use Test;
plan 1;

enum ( :Shin<ש>, :Resh<ר>, :He<ה> );

my $text = "Sarah ({Shin~Resh~He})";
my Text::FriBidi::Line $line .= new: :$text;
my $visual = $line.Str;
is-deeply $visual, "Sarah ({He~Resh~Shin})";
is $line[7], He;

```

### Multiple lines reordering (experimental)

```
use Text::FriBidi::Lines;
use Test;
plan 1;

constant $LRO = "\c[LEFT-TO-RIGHT OVERRIDE]";
constant $RLO = "\c[RIGHT-TO-LEFT OVERRIDE]";
constant $PDF = "\c[POP DIRECTIONAL FORMATTING]";

@lines = "Left", "{$RLO}Right{$PDF}", "{$LRO}left{$PDF}";
my Text::FriBidi::Lines $para .= new: :@lines;
is-deeply $para.lines, ('Left', 'thgiR', 'left');

```

## Description

The Unicode standard calls for characters to be ordered 'logically', i.e. in the sequence they are intended to be interpreted, as opposed to 'visually', the sequence they appear.

The Unicode® Bidirectional Algorithm (BiDi Algorithm) is then used to reorder for visual display.

This algorithm primarily based on character detection, but also uses special BiDi control characters available for manual control.

FriBidi is a library that implements the Unicode BiDi algorithm to reorder text for visual display. This module provides Raku
bindings to FriBidi.

## Text::FriBidi::Line Methods

### new()

```
use Text::FriBidi::Defs :FriBidiType, :FriBidiFlag;
method new(
    Str:D :$text!,      # text, in logical order
    UInt:D :$direction = FRIBIDI_TYPE_LTR, # default direction
    UInt:D :$flags = FRIBIDI_FLAGS_DEFAULT +| FRIBIDI_FLAGS_ARABIC,
)

```

#### `:$text` option

Input text, in logical reading/processing order. Possibly including [Unicode BiDi control characters](https://www.w3.org/International/questions/qa-bidi-unicode-controls.en).

## Text::FriBidi::Lines Methods

### new()

```
use Text::FriBidi::Defs :FriBidiType, :FriBidiFlag;
method new(
    Str:D :@lines!,      # paragraph lines, in logical order
    UInt:D :$direction = FRIBIDI_TYPE_LTR, # default direction
    UInt:D :$flags = FRIBIDI_FLAGS_DEFAULT +| FRIBIDI_FLAGS_ARABIC,
)

```

#### `:@lines` option

Input text lines, in logical reading/processing order. Possibly including [Unicode BiDi control characters](https://www.w3.org/International/questions/qa-bidi-unicode-controls.en).

## Common Options

#### `:$flags` option

A set of 'ored` flag, including:

* `FRIBIDI_FLAG_SHAPE_MIRRORING`: Do mirroring.
* `FRIBIDI_FLAG_SHAPE_ARAB_PRES`: Shape Arabic characters to their presentation form glyphs.
* `FRIBIDI_FLAG_SHAPE_ARAB_LIGA`: Form mandatory Arabic ligatures.
* `FRIBIDI_FLAG_REMOVE_SPECIALS`: Remove Bidi marks from output

#### `:$direction` option

Base text direction; one of:

* `FRIBIDI_TYPE_LTR`: Left to right
* `FRIBIDI_TYPE_RTL`: Right to left
* `FRIBIDI_TYPE_WLTR`: Weak left to right
* `FRIBIDI_TYPE_WRTL`: Weak right to left
* `FRIBIDI_TYPE_LTR`: Left to right
* `FRIBIDI_TYPE_RTL`: Right to left

### Str()

The string, after applying any mirroring, shaping and directional ordering and with BiDi control characters removed (by default).

### AT-POS, List, Array

Methods for obtaining individual visual characters.

Note that Raku may perform its own Unicode normalizations on strings. These
methods can be used to get corresponding characters and properties.

```
use Text::FriBidi::Line;
my Text::FriBidi::Line $line .= new(:text("A\r\nB"));
say $line.Str.comb.raku; # "A", "\r\n", "B"
say $line.List.raku; # "A" "\r" "\n" "B"
say $line[3] ~ ' has type ' ~ $line.bidi-types[3];

```

## Installation

### Debian/Ubuntu Linux

```
sudo apt-get install libfribidi-dev

```

### Mac OS X

```
brew update
brew install fribidi

```

## See Also

* [UAX #9: Unicode Bidirectional Algorithm](https://unicode.org/reports/tr9/)
* [fribidi](https://github.com/fribidi/fribidi) GitHub repository
* [Text::Bidi](https://metacpan.org/pod/Text::Bidi) Perl Module


## dist_github-PerlGameDev-SDL.md
This module provides access to the Simple DirectMedia Layer ([www.libsdl.org](http://www.libsdl.org)) to Perl6.

It makes use of NativeCall, so a C compiler is not needed in order to install this module.

## Dependencies

* libSDL, libSDL-mixer, libSDL-image

To aid NativeCall locating the libaries you should just do:

```
sudo apt install libsdl1.2-dev libsdl-mixer1.2-dev libsdl-image1.2-dev

```


## dist_zef-bbkr-JSON-RPC.md
# JSON-RPC client and server for [Raku](https://www.raku.org) language

[![.github/workflows/test.yml](https://github.com/bbkr/JSON-RPC/actions/workflows/test.yml/badge.svg)](https://github.com/bbkr/JSON-RPC/actions/workflows/test.yml)

Supports [2.0 specification](http://www.jsonrpc.org/specification).

## CLIENT

```
use JSON::RPC::Client;

# create new client with url to server
my $c = JSON::RPC::Client.new( url => 'http://127.0.0.1:8080' );

# method without params
say $c.ping;

# method with positional params
say $c.hi( 'John Doe' );

# method with named params
say $c.hello( name => 'John Doe' );

```

## SERVER

```
use JSON::RPC::Server;

# define application class
# that will handle remote procedure calls
class My::App {

    # method without params
    method ping { return 'pong' }

    # method with positional params
    method hi ( Str $name! ) { return 'Hi ' ~ $name }

    # method with named params
    method hello ( Str :$name! ) { return 'Hello ' ~ $name }

    # multi method with different signatures
    multi method offer ( Int $age where { $age < 8 } ) {
        return [ 'Toy' ];
    }
    multi method offer ( Int $age where { 8 <= $age <= 16 } ) {
        return [ 'Computer', 'Pet' ];
    }

}

# start server with your application as handler
JSON::RPC::Server.new( application => My::App ).run( );

```

Your server is now available at <http://localhost:8080>.

## ADVANCED STUFF

Examples above *make easy things easy*, now it is time to make *hard things possible*.

### Protocol versions

There are 4 specs of JSON-RPC published so far:

* [1.0](http://json-rpc.org/wiki/specification) - Not implemented. Does not support named params, error objects or batch requests and has different way of handling notifications compared to current spec. It is rarely used nowadays and because of that there are no plans to implement it, however contributions are welcome if someone wants to add backward compatibility.
* [1.1](http://web.archive.org/web/20100718181845/http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html) - Rejected. This working draft forces error reporting through HTTP codes making whole communication transport-dependent.
* [1.2](http://jsonrpc.org/historical/jsonrpc12_proposal.html) - Proposal of 2.0 (see below).
* [2.0](http://www.jsonrpc.org/specification) - Fully implemented!

### Can I use URI object to initialize client?

Use `uri` param in constructor.

```
JSON::RPC::Client.new( uri => URI.new( 'http://127.0.0.1:8080' ) );

```

### Can I bind server to port other than 8080?

Use `port` param in `run( )` method.

```
JSON::RPC::Server.new( application => My::App ).run( port => 9999 );

```

### Should I use class name or object instance as server handler?

You can use both. Using class name results in static dispatch while using object instance allows you to initialize attributes in your class.

```
class My::App {

    has $!db;
    submethod BEGIN { $!db = ... }  # connect to database

    method ping ( ) { return 'pong' }

}

# BEGIN is not called
JSON::RPC::Server.new( application => My::App ).run( );

# BEGIN is called
JSON::RPC::Server.new( application => My::App.new ).run( );

```

### How can method be excluded from server handler dispatch?

Declare it as private.

```
method !get_database_info ( ) {
    return 'username', 'password';
}

```

### Should I declare signatures for server handler methods?

It is recommended that you validate params in signatures instead of method bodies. This way server correctly returns "Invalid params" error (more info later) and method is not called if signature does not match - you can easily separate validation from logic.

```
method add_programmer (
    Str :$name!,
    Int :$age! where { $age >= 0 },
    Int :$experience! where { $experience <= $age }
) {
    # params can be trusted here
    # all fields are required and
    # negative age or experience exceeding age shall not pass
    $!db.insert( $name, $age, $experience );
}

```

### What happens when more than one server handler candidate matches?

When request can be dispatched to more than one multi method then first candidate is chosen and called. JSON-RPC protocol design does not include multi methods - it can not mimic [calling sets](https://docs.raku.org/language/operators#methodop_.*) mechanism and does not have "Ambiguous call" error in specification like Raku does. Therefore such request is not considered an error.

### Can I use my own transport layers?

This is useful when you want to use JSON-RPC on some framework which provides its own data exchange methods. It is even possible to use JSON-RPC over protocols different than HTTP.

**Client**

Pass `transport` param to `new( )` instead of `uri`/ `url` param. This should be a closure that accepts JSON request and returns JSON response.

```
sub transport ( Str :$json, Bool :$get_response ) {
    return send_request_in_my_own_way_and_obtain_response_if_needed( $request );
}

my $client = JSON::RPC::Client.new( transport => &transport );

```

Your transport will be given extra param `get_response` which informs if response is expected from the server or not (for example in case of Notification or Batch of Notifications).

**Server**

Do not `run( )` server. Instead use `handler( )` method which takes JSON request param and returns JSON response.

```
my $server = JSON::RPC::Server.new( application => My::App );

my $response = handler( json => receive_request_in_my_own_way( ) );
send_response_in_my_own_way( $_ ) with $response;

```

It is possible that request is a Notification or Batch of Notifications and `$response` is not returned from the server.

**Notifications**

When request is a Notification or Batch of Notifications then client is not expecting response and server should not return one. That is not always possible due to specification of used protocol or assumptions in framework used. In this case try to use most un:!canonicalize response possible.

For example code `204 No Content` should be used in HTTP transport.

### How to enable debugging?

**Client** has no debugging yet.

**Server** accepts `debug` param in `run( )` method.

```
JSON::RPC::Server.new( application => My::App ).run( :debug );

```

### How to implement Error handling?

Errors :!canonicalize in 2.0 spec are represented by `X::JSON::RPC` exceptions:

* `X::JSON::RPC::ParseError` - Invalid JSON was received by the server.
* `X::JSON::RPC::InvalidRequest` - The structure sent by client is not a valid Request object.
* `X::JSON::RPC::MethodNotFound` - The method does not exist in server handler application.
* `X::JSON::RPC::InvalidParams` - Invalid method parameters, no handler candidates with matching signature found.
* `X::JSON::RPC::InternalError` - Remote method died.
* `X::JSON::RPC::ProtocolError` - Other deviation from specification.

Every exception has numeric `code` attribute that indicates the error type that occurred, text `message` attribute that provides a short description of the error and optional `data` attribute that contains additional information about the error.

**Client** can catch those exceptions.

```
try {
    $c.hello( 'John Doe' );
    CATCH {
        when X::JSON::RPC::MethodNotFound {
            say 'Server is rude';
        }
        default {
            # stringified exception is in human-readable form
            say ~$_;
        }
    }
}

```

**Server** does all the exception handling automatically. For example if you provide application handler without some method client will receive "Method not found" error on call to this method. However if you want to report error from method it can be done in two ways.

* End method using die.

```
method divide ( Int $x, Int $y ) {
    die 'Cannot divide by 0' if $y ~~ 0;
    return $x / $y;
}

```

Client will receive `message` attribute "Internal error" with explanation "Cannot divide by 0" as `data` attribute.

* Throw `X::JSON::RPC` exception.

```
class My::App {
    method treasure {
        X::JSON::RPC.new( code => -1, message => 'Access denied', data => 'Thou shall not pass!' ).throw( );
    }
}

```

Exception `X::JSON::RPC` is composable so you can easily define your own errors.

```
    class My::Error does X::JSON::RPC {
        method new {
            self.bless( code => -1, message => 'Access denied', data => 'Thou shall not pass!' );
        }
    }

```

And use them in application handler.

```
method treasure {
    My::Error.new.throw( );
}

```

### How to make Notification call?

Method `'rpc.notification'( )` puts client in notification context.
Note that this method contains dot in name and it must be quoted.

```
$client.'rpc.notification'( ).heartbeat( ); # no response from this one
say $client.ping( ) # regular call again

```

You can save client context to avoid typing.

```
my $n = $client.'rpc.notification'( );
for ^1024 {
    $n.heartbeat( ); # no responses from those
}

```

### How to make Batch call?

Method `'rpc.batch'( )` puts client in batch context while method `'rpc.flush'( )` sends Requests.
Note that those methods contain dot in names and they must be quoted.

```
$client.'rpc.batch'( ).add( 2, 2 );
$client.'rpc.batch'( ).'rpc.notification'( ).heartbeat( );
$client.'rpc.batch'( ).suicide( );

for $client.'rpc.flush'( ) -> $response {
    try {
        $response.say;
        CATCH {
            when X::JSON::RPC {
                say 'Oops! ', .message;
            }
        }
    }
}

# Output:
# 4
# Opps! Suicide served.

```

Important things to remember:

* Server may process methods in Batch in any order and with any width of parallelism.
* Client will sort responses to match order in which methods were stacked.
* Notifications do not have corresponding response.
* Batch containing only Notifications will return Nil on flush.
* Attempt to flush empty Batch will result in `X::JSON::RPC::InvalidRequest` exception.
* Individual exceptions are returned as Failures, thrown when called in sink context.

You can save client context to avoid typing.

```
my $b = $client.'rpc.batch'( );
for ^1024 {
    $b.is_prime( $_ );
}
my @responses = $b.'rpc.flush'( );

```

### How to call method that has name used by language itself?

Every object instance has some methods inherited from [Mu](https://docs.raku.org/type/Mu) and [Any](https://docs.raku.org/type/Any) classes.
This rule also applies to `JSON::RPC::Client` and in rare cases you may fall into the trap.
Below example calls `Mu::can( )` instead of doing remote procedure call of method named "can".

```
$client.can( 'tuna' );

```

The workaround is to prefix method name with `rpc.`.
Note that whole name must be quoted because it contains dot.

```
$client.'rpc.can'( 'tuna' );

```

You can get full list of those troublemakers by invoking following code.

```
JSON::RPC::Client.^mro>>.^methods>>.say

```


## grammar.md
class Grammar

Formal grammar made up of named regexes

```raku
class Grammar is Match {}
```

Every type declared with `grammar`, and not explicitly stating its superclass, becomes a subclass of `Grammar`.

```raku
grammar Identifier {
    token TOP       { <initial> <rest>* }
    token initial   { <+myletter +[_]> }
    token rest      { <+myletter +mynumber +[_]> }
    token myletter  { <[A..Za..z]> }
    token mynumber  { <[0..9]> }
}

say Identifier.isa(Grammar);                # OUTPUT: «True␤»
my $match = Identifier.parse('W4anD0eR96');
say ~$match;                                # OUTPUT: «W4anD0eR96␤»
```

More [documentation on grammars](/language/grammars) is available.

# [Methods](#class_Grammar "go to top of document")[§](#Methods "direct link")

## [method parse](#class_Grammar "go to top of document")[§](#method_parse "direct link")

```raku
method parse($target, :$rule = 'TOP',  Capture() :$args = \(), Mu :$actions = Mu, *%opt)
```

Parses the `$target`, which will be coerced to [`Str`](/type/Str) if it isn't one, using `$rule` as the starting rule. Additional `$args` will be passed to the starting rule if provided.

```raku
grammar RepeatChar {
    token start($character) { $character+ }
}

say RepeatChar.parse('aaaaaa', :rule('start'), :args(\('a')));
say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')));

# OUTPUT:
# ｢aaaaaa｣
# ｢bbbbbb｣
```

If the `actions` named argument is provided, it will be used as an actions object, that is, for each successful regex match, a method of the same name, if it exists, is called on the actions object, passing the match object as the sole positional argument.

```raku
my $actions = class { method TOP($/) { say "7" } };
grammar { token TOP { a { say "42" } b } }.parse('ab', :$actions);
# OUTPUT: «42␤7␤»
```

Additional named arguments are used as options for matching, so you can for example specify things like `:pos(4)` to start parsing from the fifth (:pos is zero-based) character. All [matching adverbs](/language/regexes#Adverbs) are allowed, but not all of them take effect. There are several types of adverbs that a regex can have, some of which apply at compile time, like `:s` and `:i`. You cannot pass those to `.parse`, because the regexes have already been compiled. But, you can pass those adverbs that affect the runtime behavior, such as `:pos` and `:continue`.

```raku
say RepeatChar.parse('bbbbbb', :rule('start'), :args(\('b')), :pos(4)).Str;
# OUTPUT: «bb␤»

```

Method `parse` only succeeds if the cursor has arrived at the end of the target string when the match is over. Use [method subparse](/routine/subparse) if you want to be able to stop in the middle.

The top regex in the grammar will be allowed to backtrack.

Returns a [`Match`](/type/Match) on success, and [`Nil`](/type/Nil) on failure.

## [method subparse](#class_Grammar "go to top of document")[§](#method_subparse "direct link")

```raku
method subparse($target, :$rule = 'TOP', Capture() :$args = \(),  Mu :$actions = Mu, *%opt)
```

Does exactly the same as [method parse](/routine/parse), except that cursor doesn't have to reach the end of the string to succeed. That is, it doesn't have to match the whole string.

Note that unlike [method parse](/routine/parse), `subparse` *always* returns a [`Match`](/type/Match), which will be a failed match (and thus falsy), if the grammar failed to match.

```raku
grammar RepeatChar {
    token start($character) { $character+ }
}

say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('b')));
say RepeatChar.parse(   'bbbabb', :rule('start'), :args(\('b')));
say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')));
say RepeatChar.subparse('bbbabb', :rule('start'), :args(\('a')), :pos(3));

# OUTPUT:
# ｢bbb｣
# Nil
# #<failed match>
# ｢a｣
```

## [method parsefile](#class_Grammar "go to top of document")[§](#method_parsefile "direct link")

```raku
method parsefile(Str(Cool) $filename, :$enc, *%opts)
```

Reads file `$filename` encoding by `$enc`, and parses it. All named arguments are passed on to [method parse](/routine/parse).

```raku
grammar Identifiers {
    token TOP        { [<identifier><.ws>]+ }
    token identifier { <initial> <rest>* }
    token initial    { <+myletter +[_]> }
    token rest       { <+myletter +mynumber +[_]> }
    token myletter   { <[A..Za..z]> }
    token mynumber   { <[0..9]> }
}

say Identifiers.parsefile('users.txt', :enc('UTF-8'))
    .Str.trim.subst(/\n/, ',', :g);

# users.txt :
# TimToady
# lizmat
# jnthn
# moritz
# zoffixznet
# MasterDuke17

# OUTPUT: «TimToady,lizmat,jnthn,moritz,zoffixznet,MasterDuke17␤»
```

# [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")

Type relations for `Grammar`

raku-type-graph

Grammar
Grammar

Match
Match

Grammar->Match

Mu
Mu

Any
Any

Any->Mu

Capture
Capture

Capture->Any

Cool
Cool

Cool->Any

Match->Capture

Match->Cool

[Expand chart above](/assets/typegraphs/Grammar.svg)


## dist_zef-raku-community-modules-Concurrent-Queue.md
[![Actions Status](https://github.com/raku-community-modules/Concurrent-Queue/actions/workflows/linux.yml/badge.svg)](https://github.com/raku-community-modules/Concurrent-Queue/actions) [![Actions Status](https://github.com/raku-community-modules/Concurrent-Queue/actions/workflows/macos.yml/badge.svg)](https://github.com/raku-community-modules/Concurrent-Queue/actions) [![Actions Status](https://github.com/raku-community-modules/Concurrent-Queue/actions/workflows/windows.yml/badge.svg)](https://github.com/raku-community-modules/Concurrent-Queue/actions)

# NAME

Concurrent::Queue - A lock-free concurrent queue data structure

# SYNOPSIS

```
use Concurrent::Queue;

my $queue = Concurrent::Queue.new;
$queue.enqueue('who');
$queue.enqueue('what');
$queue.enqueue('why');
say $queue.dequeue;       # who
say ?$queue;              # True
say $queue.elems;         # 2
say $queue.Seq;           # (what why)
say $queue.list;          # (what why)
say $queue.dequeue;       # what
$queue.enqueue('when');
say $queue.dequeue;       # why
say $queue.dequeue;       # when
say ?$queue;              # False
say $queue.elems;         # 0

my $val = $queue.dequeue;
say $val.WHO;             # Failure
say $val.exception.WHO;   # X::Concurrent::Queue::Empty

```

# DESCRIPTION

Lock-free data structures may be safely used from multiple threads, yet do not use locks in their implementation. They achieve this through the use of atomic operations provided by the hardware. Nothing can make contention between threads cheap - synchronization at the CPU level is still synchronization - but lock-free data structures tend to scale better.

This lock-free queue data structure implements an [algorithm described by Maged M. Michael and Michael L. ScottL](https://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf). The only (intended) differences are:

* A `Failure` is returned to indicate emptiness, rather than a combination of boolean return value and out parameter, in order that this type feels more natural to Raku language users
* There is an out-of-band element count (which doesn't change the algorithm at all, just increments and decrements the count after an enqueue/dequeue)
* Raku doesn't need ABA-problem mitigation thanks to having GC

The `elems` and `Bool` method should not be used to decide whether to dequeue, unless it is known that no other thread could be performing an enqueue or dequeue at the same time. Their only use in the presence of concurrent use of the queue is for getting an approximate idea of queue size. In the presence of a single thread, the element count will be accurate (so if many workers were to enqueue data, and are known to have completed, then at that point the `elems` will be an accurate reflection of how many values were placed in the queue).

Note that there is no blocking dequeue operation. If looking for a blocking queue, consider using the Raku built-in `Channel` class. (If tempted to write code that sits in a loop testing if `dequeue` gives back a `Failure` - don't. Use `Channel` instead.)

# METHODS

## enqueue(Any $value)

Puts the value into the queue at its tail. Returns `Nil`.

## dequeue()

If the queue is not empty, removes the head value and returns it. Otherwise, returns a `Failure` containing an exception of type `X::Concurrent::Queue::Empty`.

## elems()

Returns the number of elements in the queue. This value can only be relied upon when it is known that no threads are interacting with the queue at the point this method is called. **Never** use the result of `elems` to decide whether to `dequeue`, since another thread may `enqueue` or `dequeue` in the meantime. Instead, check if `dequeue` returns a `Failure`.

## Bool()

Returns `False` if the queue is empty and `True` if the queue is non-empty. The result can only be relied upon when it is known that no other threads are interacting with the queue at the point this method is called. **Never** use the result of `Bool` to decide whether to `dequeue`, since another thread may `enqueue` or `dequeue` in the meantime. Instead, check if `dequeue` returns a `Failure`.

## Seq

Returns a `Seq` that will iterate the queue contents. The iteration will include all values that had not been dequeued at the point the `Seq` method was called. Additionally, it will incorporate any values that are enqueued during the iteration, meaning that if values are being enqueued at a rate at least as fast as the iteration is visiting them then the iteration may not terminate.

If wanting to prevent this, consider limiting the result length to that of the result of `elems` (e.g. `$cq.head($cq.elems)`). If using the queue to collect values in many threads and then iterate them in one thread afterwards, this is not a concern, since nothing will be enqueueing further values at that point. However, consider using `Concurrent::Stack` instead, since a concurrent stack's operations are cheaper than those of a concurrent queue (the same algorithmic order, but a lower constant factor).

## list

Equivalent to `.Seq.list`; see the description of `Seq` for caveats, and remember that a `List` preserves its elements, so the potentially endless iteration could also eat endless memory.

# AUTHOR

Jonathan Worthington

# COPYRIGHT AND LICENSE

Copyright 2018 - 2022 Jonathan Worthington

Copyright 2024 Raku Community

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_cpan-PMQS-IO-Compress.md
```

                            IO-Compress

                           Version 2.094

                            13 July 2020

       Copyright (c) 1995-2020 Paul Marquess. All rights reserved.
          This program is free software; you can redistribute it
           and/or modify it under the same terms as Perl itself.

DESCRIPTION
-----------

This distribution provides a Perl interface to allow reading and writing of
compressed data created with the zlib and bzip2.

IO-Compress supports reading and writing of the following compressed data formats
  * bzip2
  * RFC 1950
  * RFC 1951
  * RFC 1952 (i.e. gzip)
  * zip

There are a number of companion modules for IO-Compress that extend
the suite of compression formats available.

 * IO-Compress-Lzma
   Adds support for lzma, xz and lzip.
 * IO-Compress-Lzf
   Adds support for lzf.
 * IO-Compress-Lzop
   Adds support for lzop.

Note that the following modules used to be distributed separately, but are now
included with the IO-Compress distribution.

    Compress-Zlib
    IO-Compress-Zlib
    IO-Compress-Bzip2
    IO-Compress-Base

PREREQUISITES
-------------

Before you can build IO-Compress you need to have the following
installed on your system:

    * Perl 5.006 or better.
    * Compress::Raw::Zlib
    * Compress::Raw::Bzip2

BUILDING THE MODULE
-------------------

Assuming you have met all the prerequisites, the module can now be built
using this sequence of commands:

    perl Makefile.PL
    make
    make test

INSTALLATION
------------

To install IO-Compress, run the command below:

    make install

TROUBLESHOOTING
---------------

SUPPORT
-------

General feedback/questions/bug reports should be sent to
https://github.com/pmqs/IO-Compress/issues (preferred) or
https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress.

FEEDBACK
--------

How to report a problem with IO-Compress.

To help me help you, I need all of the following information:

 1. The Versions of everything relevant.
    This includes:

     a. The *complete* output from running this

            perl -V

        Do not edit the output in any way.
        Note, I want you to run "perl -V" and NOT "perl -v".

        If your perl does not understand the "-V" option it is too
        old. This module needs Perl version 5.004 or better.

     b. The version of IO-Compress you have.
        If you have successfully installed IO-Compress, this one-liner
        will tell you:

           perl -MIO::Compress::Gzip -e 'print qq[ver $IO::Compress::Gzip::VERSION\n]'

        If you are  running windows use this

           perl -MIO::Compress::Gzip -e "print qq[ver $IO::Compress::Gzip::VERSION\n]"

        If you haven't installed IO-Compress then search IO::Compress::Gzip.pm
        for a line like this:

          $VERSION = "2.094" ;

 2. If you are having problems building IO-Compress, send me a
    complete log of what happened. Start by unpacking the IO-Compress
    module into a fresh directory and keep a log of all the steps

        [edit config.in, if necessary]
        perl Makefile.PL
        make
        make test TEST_VERBOSE=1

Paul Marquess

```


## dist_zef-rbt-Net-DNS.md
# Net::DNS

A simple DNS resolver.

Note: If you are behind a firewall that blocks Google DNS, you will need to set
DNS\_TEST\_HOST in your environment to pass the tests.

## Example Usage

```
my $resolver = Net::DNS.new('8.8.8.8'); # google dns server

my @mx-ips = $resolver.lookup-mx('gmail.com');

my @all = $resolver.lookup-ips('google.com');
my @ipv4 = $resolver.lookup-ips('google.com', :inet);
my @ipv6 = $resolver.lookup-ips('google.com', :inet6);

my @dns-answers = $resolver.lookup('A', 'google.com'); # ("1.2.3.4", "5.6.7.8", ...)

```

## Methods

* `new(Str $host, $socket = IO::Socket::INET)`

  Creates a new DNS resolver using the specified DNS server.

  The `$socket` parameter lets you inject your own socket class to use for the
  query (so you can do a proxy negotiation or somesuch first).
* `lookup-ips(Str $name, :$inet, :$inet6)`

  Looks up the specified $name, looking for A and AAAA records (only searches
  for A when :inet is specified, and only searches for AAAA when :inet6 is
  specified). Will chase down CNAME records to get you the actual IP
  addresses. Will return a list of A and AAAA responses.
* `lookup-mx(Str $name, :$inet, :$inet6)`

  Does a lookup for MX records, and then internally calls `lookup-ips` to
  find the actual addresses for the mailservers. Returns a list of A and AAAA
  records, in MX priority order.
* `lookup(Str $type, Str $name)`

  Looks up the specified $name, looking for records of $type. Returns a list of
  response classes, specified below. A failed lookup returns an empty list.

## Supported DNS Types

The return of a lookup is a list of classes. Which class depends on the request
type.

The object returned will stringify to something useful, and will also provide
attributes to access each piece of information that was returned.

Note that all of these classes also have a `@.owner-name` attribute. Normally this
is the same as the domain name you did the lookup on.

* `A`

  Returns a class with attribute `@.octets`, which will have 4 elements.

  Stringifies to an ip address ("192.168.0.1")
* `AAAA`

  Returns a class with attribute `@.octets`, which will have 16 elements.

  Stringifies to an ipv6 address ("2607:f8b0:…")
* `CNAME`

  Returns a class with attribute `@.name`, which is a domain name split on '.'.
  To get the full domain name, call $object.name.join('.');

  Stringifies to a domain name.
* `MX`

  Returns a class with attributes `$.priority`, `@.name`.

  Stringifies to a domain name.
* `NS`

  Returns a class with attribute `@.name`

  Stringifies to a domain name.
* `PTR`

  Returns a class with attribute `@.name`

  Stringifies to a domain name.
* `RRSIG`

  Returns a class with attributes `$.type-covered`, `$.algorithm`,
  `$.labels`, `$.original-ttl`, `$.signature-expiration`,
  `$.signature-inception`, `$.key-tag`, `$.signer-name`, and
  `$.signature`.

  Stringifies to a a string with similar output to the output produced
  by the `dig` command line utility.

  Note that this module does not validate the validity of a DNSSEC signature.
* `SRV`

  Returns a class with the attributes `$.priority`, `$.weight`, `$.port`, `@.name`.

  Stringifies to "the.server:port".
* `SPF`

  Returns a class with the attribute `$.text`

  Stringifies to the text
* `TXT`

  Returns a class with the attribute `$.text`

  Stringifies to the text
* `SOA`

  Returns a class with the attributes `@.mname`, `@.rname`, `$.serial`, `$.refresh`,
  `$.retry`, `$.expire`, `$.minimum`

  Stringifies to a format similar to nslookup
* `AXFR`

  Zone transfer request.

  This is a special case - it returns a list of the above objects instead of it's
  own response type.

## Exceptions

DNS Server errors will produce a Failure response on lookup(), lookup-ips(), and lookup-mx() with an X::Net::DNS object.

* server-message

  A complete Net::DNS::Message structured response from the server.
* rcode-value

  Return code Integer received from the DNS server.
* rcode-name

  [Return code name](https://support.umbrella.com/hc/en-us/articles/232254248-Common-DNS-return-codes-for-any-DNS-service-and-Umbrella-)
  received from the DNS server. Common values are SERVFAIL and NXDOMAIN.
* message

  A short english message which might be shown to users.


## dist_cpan-GDONALD-BDD-Behave.md
## Behave

A behavior driven development framework written in [Perl 6](https://perl6.org/).

Currently developed against Rakudo `v6.d`.

#### Install using zef

```
zef install BDD::Behave

```

#### Running Behave:

If a file is not specificed Behave will automatically look for a `specs` directory and will run anything matching `/spec.p6/`.

#### An example:

**specs/001-spec.p6**

```
use BDD::Behave;

describe -> 'this spec' {
  it -> 'passes' {
    expect(42).to.be(42);
  }
}

describe -> 'this final spec' {
  it -> 'fails at line 12' {
    expect(42).to.be(41);
  }
}

```

You can run the spec like this:

```
$ behave specs/001-spec.p6

```

Output:

```
specs/001-spec.p6

    ⮑  'this spec'
        ⮑  'passes'
            ⮑  SUCCESS

    ⮑  'this final spec'
        ⮑  'fails at line 12'
            ⮑  FAILURE

Failures:

  [ ✗ ] specs/001-spec.p6:12

```

#### Status

[![Build Status](https://travis-ci.org/gdonald/BDD-Behave.svg?branch=master)](https://travis-ci.org/gdonald/BDD-Behave)

#### Documentation

No docs yet, see the examples in [specs/\*](https://github.com/gdonald/BDD-Behave/tree/master/specs).

#### License

Behave is released under the [Artistic License 2.0](https://opensource.org/licenses/Artistic-2.0)


## twigil.md
class X::Syntax::Variable::Twigil

Compilation error due to an unallowed twigil in a declaration

```raku
class X::Syntax::Variable::Twigil does X::Syntax { }
```

Syntax error thrown when a variable with a twigil is used in an incompatible declaration.

For example

```raku
my $!foo;

```

dies with

｢text｣ without highlighting

```

```

===SORRY!===
Cannot use ! twigil on my variable

```

```

# [Methods](#class_X::Syntax::Variable::Twigil "go to top of document")[§](#Methods "direct link")

## [method twigil](#class_X::Syntax::Variable::Twigil "go to top of document")[§](#method_twigil "direct link")

```raku
method twigil(--> Str:D)
```

Returns the twigil that was illegally used

## [method scope](#class_X::Syntax::Variable::Twigil "go to top of document")[§](#method_scope "direct link")

```raku
method scope(--> Str:D)
```

Returns the scope that did not harmonize with the twigil.


## distribution.md
role Distribution

Distribution

```raku
role Distribution { }
```

This role is an interface for objects that provide API access mapping META6 data to the files it represents. Objects that fulfill the `Distribution` role can be read by e.g. [`CompUnit::Repository::Installation`](/type/CompUnit/Repository/Installation). Generally a `Distribution` provides read access to a set of modules and metadata. These may be backed by the filesystem ([`Distribution::Path`](/type/Distribution/Path), [`Distribution::Hash`](/type/Distribution/Hash)) but could also read from an e.g. tar file or socket.

# [Required Methods](#role_Distribution "go to top of document")[§](#Required_Methods "direct link")

## [method meta](#role_Distribution "go to top of document")[§](#method_meta "direct link")

```raku
method meta(--> Hash:D) { ... }
```

Returns a Hash with the representation of the metadata. Please note that an actual `META6.json` file does not need to exist, just a representation in that format.

## [method content](#role_Distribution "go to top of document")[§](#method_content "direct link")

```raku
method content($name-path --> IO::Handle:D) { ... }
```

Returns an [`IO::Handle`](/type/IO/Handle) to the file represented by `$name-path`. `$name-path` is a relative path as it would be found in the metadata such as `lib/Foo.rakumod` or `resources/foo.txt`.

# [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")

Type relations for `Distribution`

raku-type-graph

Distribution
Distribution

Distribution::Locally
Distribution::Locally

Distribution::Locally->Distribution

Mu
Mu

Any
Any

Any->Mu

Distribution::Path
Distribution::Path

Distribution::Path->Distribution::Locally

Distribution::Path->Any

Distribution::Hash
Distribution::Hash

Distribution::Hash->Distribution::Locally

Distribution::Hash->Any

[Expand chart above](/assets/typegraphs/Distribution.svg)


## dist_zef-witawayar-Slang-Forgiven.md
## Slang::Forgiven

When a for loop meets a given statement

```
use Slang::Forgiven;

# `$num` as well as `$_` are available in the loop body
forgiven [2, -3, 4, -5] -> $num {
    # `$_` is aliased to `$num`, so `when` will know
    when * > 0 { put "$num is positive" }
    when * < 0 { put "$num is negative" }
    default    { put "neutral" }
}

```

### What

A for loop with a parametrized block lets you iterate over things with names, and a given statement allows for topicalization. The "forgiven" statement does both: you have the usual looping but also have `$_` available.

That is,

```
for @values -> $val {
    given $val {
        when * > 0 { "$val is positive" }
        ...
    }
}

```

is possible as

```
forgiven @values -> $val {
    when * > 0 { "$val is positive" }
    ...
}

```

i.e., it's as if `$_ := $val` is placed immediately after the opening curly bracket. Arrays, Hashes, their destructuring, optional and/or typed parameters are possible, too; examples for them can be found in the "t/" directory.

### Why

"For fun" should be enough but this also came up in at least 2 places:

* "habere-et-disper" (~"tire") [on IRC](https://irclogs.raku.org/raku-beginner/2022-11-10.html#10:26) mentions the "-Ofun idea of `forgiven`"
* "VZ." asks about an "elegant way to write when inside a for loop" [on StackOverflow](https://stackoverflow.com/questions/75186531)

I thank "habere-et-dispertire" for the idea; this arose from their message(s). They informed me that "deoac" on [exercism](https://exercism.org/tracks/raku) had mentioned it originally; so thanks to them as well! I also thank Damian Conway for their [for-else](https://blogs.perl.org/users/damian_conway/2019/09/itchscratch.html) writing (as well as the numerous presentations online that leave me amazed).

### How

Grammar follows that of the "for" loop. Actions first gather the parameter names of the block of the loop, and then unshift the `$_ := ...` statement (a "bind" QAST::Op) to the AST of the statement list of the block.

#### Installation

Using [pakku](https://github.com/hythm7/Pakku):

```
git clone https://github.com/mustafaaydn/Slang-Forgiven.git && cd "$(basename "$_" .git)"
pakku add . && cd .. && rm -rf Slang-Forgiven

```


## dist_github-cbk-WebService-GoogleDyDNS.md
# WebService::DyDNS [Build Status](https://travis-ci.org/cbk/WebService-GoogleDyDNS)

## SYNOPSIS

Simple web service used to update an IP address on domains.google.com if the current one has changed.
Obtains current IP address using the WebService::HazIP module, then compares the results with the IP
address that was set the last time the service was ran. It there was a change, the updateIP() method
is then called to update the IP address using the HTTP::UserAgent module.

## TODO

* Maybe POST request would be better

## Methods

* checkPreviousIP()
* updateIP()

## Returns

* One of the response codes from domains.google.com
* "No change. No action taken."

## Example usage:

```
use v6;
use WebService::GoogleDyDNS;

multi sub MAIN( :$domain, :$login, :$password ) {

  my $updater = WebService::GoogleDyDNS.new(domainName => $domain, login => $login , password => $password );
  $updater.checkPreviousIP();
  if $updater.outdated { say $updater.updateIP(); } else { say "No change. No action taken."; }

}

```