Convert "sl" Source Code from C to Rust

Previous - Draw a Train

Put All Graphic Images Into A Separate File

Move the Graphics Images into a Separate File

Let's go ahead and put all our images into the separate file, "images.rs", and while we're at it, we'll add a few images.

src/images.rs
/* images.rs */

/*  Feel free to add your own images, and modify the rest of the program code accordingly.
    - Ideally all the lines of all the frames of a particular image should be of
        the same length. But if not, the first line of the first frame should be
        the longest, as that's the line the program uses to determine an image's
        length.
    - If there are multiple frames/cels of the image, a blank line must separate the frames.
    - The single quotes at the end of the lines are optional; they merely serve as a visual
        indicator of the end of the line. Some of the image lines have the single quote;
        some do not. The program will strip them out if they are included here.
    - The "r" before the string tells the compiler to read the string in "raw"
        mode, so that backslashes are not interpreted as escape characters.
    - If a hash/splat ("#") is used in an image, the "r" must be modified to be "r#", and
        the end of the string must be closed with a "#". You can see this in both the
        TWINENGINE and MOTORCYCLE declarations.

Original Copyright Notice from "sl.h" in the "sl" package of Debian Bookworm:

/*========================================
 *    sl.h: SL version 5.02
 *      Copyright 1993,2002,2014
 *                Toyoda Masashi
 *                (mtoyoda@acm.org)
 *      Last Modified: 2014/06/03
 *========================================
 */

 This Rust re-write by:
  Kent West - kent.west@gmail.com
  July 2023
*/

pub const D51: &str = r"
      ====        ________                ___________'
  _D _|  |_______/        \__I_I_____===__|_________|'
   |(_)---  |   H\________/ |   |        =|___ ___|  '
   /     |  |   H  |  |     |   |         ||_| |_||  '
  |      |  |   H  |__--------------------| [___] |  '
  | ________|___H__/__|_____/[][]~\_______|       |  '
  |/ |   |-----------I_____I [][] []  D   |=======|__'
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__'
 |/-=|___|=    ||    ||    ||    |_____/~\___/       '
  \_/      \O=====O=====O=====O_/      \_/           '

      ====        ________                ___________
  _D _|  |_______/        \__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |        =|___ ___|  
   /     |  |   H  |  |     |   |         ||_| |_||  
  |      |  |   H  |__--------------------| [___] |  
  | ________|___H__/__|_____/[][]~\_______|       |  
  |/ |   |-----------I_____I [][] []  D   |=======|__
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__
 |/-=|___|=O=====O=====O=====O   |_____/~\___/       
  \_/      \__/  \__/  \__/  \__/      \_/           

      ====        ________                ___________'
  _D _|  |_______/        \__I_I_____===__|_________|'
   |(_)---  |   H\________/ |   |        =|___ ___|  '
   /     |  |   H  |  |     |   |         ||_| |_||  '
  |      |  |   H  |__--------------------| [___] |  '
  | ________|___H__/__|_____/[][]~\_______|       |  '
  |/ |   |-----------I_____I [][] []  D   |=======|__'
__/ =| o |=-O=====O=====O=====O \ ____Y___________|__'
 |/-=|___|=    ||    ||    ||    |_____/~\___/       '
  \_/      \__/  \__/  \__/  \__/      \_/           '

      ====        ________                ___________
  _D _|  |_______/        \__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |        =|___ ___|  
   /     |  |   H  |  |     |   |         ||_| |_||  
  |      |  |   H  |__--------------------| [___] |  
  | ________|___H__/__|_____/[][]~\_______|       |  
  |/ |   |-----------I_____I [][] []  D   |=======|__
__/ =| o |=-~O=====O=====O=====O\ ____Y___________|__
 |/-=|___|=    ||    ||    ||    |_____/~\___/       
  \_/      \__/  \__/  \__/  \__/      \_/           

      ====        ________                ___________'
  _D _|  |_______/        \__I_I_____===__|_________|'
   |(_)---  |   H\________/ |   |        =|___ ___|  '
   /     |  |   H  |  |     |   |         ||_| |_||  '
  |      |  |   H  |__--------------------| [___] |  '
  | ________|___H__/__|_____/[][]~\_______|       |  '
  |/ |   |-----------I_____I [][] []  D   |=======|__'
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__'
 |/-=|___|=   O=====O=====O=====O|_____/~\___/       '
  \_/      \__/  \__/  \__/  \__/      \_/           '

      ====        ________                ___________
  _D _|  |_______/        \__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |        =|___ ___|  
   /     |  |   H  |  |     |   |         ||_| |_||  
  |      |  |   H  |__--------------------| [___] |  
  | ________|___H__/__|_____/[][]~\_______|       |  
  |/ |   |-----------I_____I [][] []  D   |=======|__
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__
 |/-=|___|=    ||    ||    ||    |_____/~\___/       
  \_/      \_O=====O=====O=====O/      \_/           
";

pub const LITTLE: &str = r"
     ++      +------ ____                 ____________________ '
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--O========O~\-+  |__________________| |__________________| '
//// \_/      \_/       (O)       (O)        (O)        (O)    '

     ++      +------ ____                 ____________________ ' 
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--/O========O\-+  |__________________| |__________________| '
//// \_/      \_/       (O)       (O)        (O)        (O)    '

     ++      +------ ____                 ____________________ '
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--/~O========O-+  |__________________| |__________________| '
//// \_/      \_/       (O)       (O)        (O)        (O)    '

     ++      +------ ____                 ____________________ '
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--/~\------/~\-+  |__________________| |__________________| '
//// \_O========O       (O)       (O)        (O)        (O)    '

     ++      +------ ____                 ____________________ '
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--/~\------/~\-+  |__________________| |__________________| '
//// \O========O/       (O)       (O)        (O)        (O)    '

     ++      +------ ____                 ____________________ '
     ||      |+-+ |  |   \@@@@@@@@@@@     |  ___ ___ ___ ___ | '
   /---------|| | |  |    \@@@@@@@@@@@@@_ |  |_| |_| |_| |_| | '
  + ========  +-+ |  |                  | |__________________| '
 _|--/~\------/~\-+  |__________________| |__________________| '
//// O========O_/       (O)       (O)        (O)        (O)    '

"; // end of LITTLE

pub const C51: &str = r"
        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|==[]=-     ||      ||      |  ||=======_|__'
/~\____|___|/~\_|   O=======O=======O  |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '

        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|===[]=-    ||      ||      |  ||=======_|__'
/~\____|___|/~\_|    O=======O=======O |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '

        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|===[]=- O=======O=======O  |  ||=======_|__'
/~\____|___|/~\_|      ||      ||      |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '

        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|==[]=- O=======O=======O   |  ||=======_|__'
/~\____|___|/~\_|      ||      ||      |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '

        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|=[]=- O=======O=======O    |  ||=======_|__'
/~\____|___|/~\_|      ||      ||      |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '

        ___                                            '
       _|_|_  _     __       __             ___________'
    D__/   \_(_)___|  |__H__|  |_____I_Ii_()|_________|'
     | `---'   |:: `--'  H  `--'         |  |___ ___|  '
    +|~~~~~~~~++::~~~~~~~H~~+=====+~~~~~~|~~||_| |_||  '
    ||        | ::       H  +=====+      |  |::  ...|  '
|    | _______|_::-----------------[][]-----|       |  '
| /~~ ||   |-----/~~~~\  /[I_____I][][] --|||_______|__'
------'|oOo|=[]=-      ||      ||      |  ||=======_|__'
/~\____|___|/~\_|  O=======O=======O   |__|+-/~\_|     '
\_/         \_/  \____/  \____/  \____/      \_/       '
"; // end of C51

pub const BOAT: &str = r"
   |\     '
   | \    '
   |  \   '
   |___\  '
\--|----/ '
 \_____/  '
"; // end of BOAT

// This string uses double-quotes, so we have to wrap it in #""# instead of just "".
pub const TWINENGINE: &str = r#"
                                                                .____   __ _      
   __o__   _______ _ _  _                                     /     /             
   \    ~\                                                  /      /              
     \     '\                                         ..../      .'               
      . ' ' . ~\                                      ' /       /                 
     .  |    .  ~ \  .+~\~ ~ ' ' " " ' ' ~ - - - - - -''_      /                  
    .  <#  .  - - -/' . ' \  __                          '~ - \                   
     .. -           ~-.._ / |__|  ( )  ( )  ( )  0  o    _ _    ~ .               
   .-'                                               .- ~    '-.    -.            
  <                      . ~ ' ' .             . - ~             ~ -.__~_. _ _    
    ~- .       N121PP  .       /  . . . . ,- ~                                    
          ' ~ - - - - =.   <#>    .         \.._                                  
                      .     ~      ____ _ .. ..  .- .                             
                       .  /      '        ~ -.        ~ -.                        
                         ' . . '               ~ - .       ~-.                    
                                                     ~ - .      ~ .               
                                                            ~ -...0..~. ____      

                                                                .____   __ _      
   __o__   _______ _ _  _                                     /     /             
   \    ~\                                                  /      /              
     \     '\                                         ..../      .'               
      . ' ' . ~\                                      ' /       /                 
     .  _    .  ~ \  .+~\~ ~ ' ' " " ' ' ~ - - - - - -''_      /                  
    .  <# -.  - - -/' . ' \  __                          '~ - \                   
     .. -           ~-.._ / |__|  ( )  ( )  ( )  0  o    _ _    ~ .               
   .-'                                               .- ~    '-.    -.            
  <                      . ~ ' ' .             . - ~             ~ -.__~_. _ _    
    ~- .       N121PP  .          . . . . ,- ~                                    
          ' ~ - - - - =. - <#> -  .         \.._                                  
                      .     ~      ____ _ .. ..  .- .                             
                       .         '        ~ -.        ~ -.                        
                         ' . . '               ~ - .       ~-.                    
                                                     ~ - .      ~ .               
                                                            ~ -...0..~. ____      

                                                                .____   __ _      
   __o__   _______ _ _  _                                     /     /             
   \    ~\                                                  /      /              
     \     '\                                         ..../      .'               
      . ' ' . ~\                                      ' /       /                 
     .    /  .  ~ \  .+~\~ ~ ' ' " " ' ' ~ - - - - - -''_      /                  
    . -<#  .  - - -/' . ' \  __                          '~ - \                   
     .. -           ~-.._ / |__|  ( )  ( )  ( )  0  o    _ _    ~ .               
   .-'                                               .- ~    '-.    -.            
  <                      . ~ ' ' .             . - ~             ~ -.__~_. _ _    
    ~- .       N121PP  . \        . . . . ,- ~                                    
          ' ~ - - - - =.   <#>    .         \.._                                  
                      .     ~      ____ _ .. ..  .- .                             
                       .      \  '        ~ -.        ~ -.                        
                         ' . . '               ~ - .       ~-.                    
                                                     ~ - .      ~ .               
                                                            ~ -...0..~. ____      

                                                                .____   __ _      
   __o__   _______ _ _  _                                     /     /             
   \    ~\                                                  /      /              
     \     '\                                         ..../      .'               
      . ' ' . ~\                                      ' /       /                 
     .  _    .  ~ \  .+~\~ ~ ' ' " " ' ' ~ - - - - - -''_      /                  
    .  <# -.  - - -/' . ' \  __                          '~ - \                   
     .. -           ~-.._ / |__|  ( )  ( )  ( )  0  o    _ _    ~ .               
   .-'                                               .- ~    '-.    -.            
  <                      . ~ ' ' .             . - ~             ~ -.__~_. _ _    
    ~- .       N121PP  .          . . . . ,- ~                                    
          ' ~ - - - - =. - <#> -  .         \.._                                  
                      .     ~      ____ _ .. ..  .- .                             
                       .         '        ~ -.        ~ -.                        
                         ' . . '               ~ - .       ~-.                    
                                                     ~ - .      ~ .               
                                                            ~ -...0..~. ____      
"#; // end of TWINENGINE

pub const PLANE: &str = r"
   ____       _  '
| __\_\_o____/_| '
<[___\_\_-----<  '
|  o'            '
                 '
                 '

   ____       _  '
/ __\_\_o____/_| '
<[___\_\_-----<  '
\  o'            '
                 '
                 '

   ____       _  '
| __\_\_o____/_| '
<[___\_\_-----<  '
|  o'            '
                 '
                 '

   ____       _  '
\ __\_\_o____/_| '
<[___\_\_-----<  '
/  o'            '
                 '
                 '
"; // end of PLANE

pub const MOTORCYCLE: &str = r#"
                        _
                       ,S/  .e.##ee
                     ,SS/_ /#####""
                   ,SSSSSS`|##|
                 ,'|SSSSSS/%##|
                 | ;SSSSS/%%%/ .-""-._                           __..ooo._.sSSSSSSSSS"7.
                 |/SSSSS/%%%/.'       `._ __               _.od888888888888"'  '"SSSSS"
             ___  `"SSS/%%%/"-.,sSSs._   8888o._    __.o888888888""SS""    `-._    `7Sb
      _.sssSSSSSSSSSSS/`%%/ ,sSSSSSSSSS-.888888888888888888888"'.S"         ,SSS""   `7b
   ,+""       ```""SS/%%./,sSSSSSSSS".   `"888888888888888"'.sSS"         ,SS"'        `S.
                    /%%%/sSSSSSSSS"   `s.   `"88888888"'.sSSSS"         ,S"'             7
                   /%%%/ `SSSSSSS$$,..sSS`-.   `"88'.sSSSSSSSS._     ,-'
                  /%%%/    `SSSS$$$$SSS",\\\`-.   `"SSSSSS"  8"""7.-'
                  /`%/      `SS$$$SSS,dP,s.\\//`-.   `SS" ,'`8       ,ee888888ee.
        ,oo8888oo/ /         `"""",d88Pd8888./,-'/`.  `,-._`d'    ,d88888888888888b.
     ,d888888888/ /8b.          d8888Pd8888888bd88b`.  :_._`8   ,888888"'    '""88888.
   ,888P'      / /"888b.       d88888`8888888Pd8888 :  :_`-.( ,d8888.__           7888b.
  d88P        / /   `788b     (88888:. `8888Pd88888 ;  ; `-._ 8888P_Z_.>-""--.._   `8888
 d88'     ,--/ /      `88b     `88888b`. `8P 78888";  ;      `"*88_,"   s88s.       `888b
d88'    ,',$/ /$$$$.   `88b      `8888b `. `"'88"_/_,'`-._         `-.d8"88"8P.      `888.
888    ; ,$$$$$$$$$'    888        `"8'   `---------------`-.._      8888888888       888'
888    : `$$$$$$$':     888                                 '888b`-._8s888888"P      .888'
788.   `  `$$$$'  ;     88P                                  8888.   "8878888P'      d888
 88b    `.  `"' ,'     d88'                                  '888b     '88s8"'     .d888'
 `88b.    `-..-'      d88'                                    '888b.             .dd888'
   788b.            ,888'                                       7888b._       _.d8888P
    `7888oo..__..oo888'                                          `"8888888888888888"'
      `"7888888888P"'                                               `"788 mGk 8P"'
"#; // end of MOTORCYCLE

pub const JACK: &str = r"
 \ 0 /   '
  \|/    '
   |     '
  / \    '
_/   \_  '

         '
 __0__   '
/  |  \  '
  / \    '
 _\ /_   '

         '
   o     '
 /\ /\   '
 |/ \|   '
 _\ /_   '

         '
 __0__   '
/  |  \  '
  / \    '
 _\ /_   '
"; // end of JACK

pub const COALCAR: &str = r"
                              '
                              '
                              '
    _________________         '
   _|                \_____A  '
 =|                        |  '
 -|                        |  '
__|________________________|_ '
|__________________________|_ '
   |_D__D__D_|  |_D__D__D_|   '
    \_/   \_/    \_/   \_/    '
"; // end of COALCAR

pub const FERRIS: &str = r"
       _~^~^~_     '
  \)  /  o o  \  (/'
    \'_   -   _'/  '
     / '-----' \   '

       _~^~^~_     '
  \)  /  o o  \  (/'
    \'_   -   _'/  '
     / '-----' \   '

       _~^~^~_     '
  \)  /  o o  \  (/'
    \'_   -   _'/  '
     / '-----' \   '

       _~^~^~_     '
  \)  /  o o  \  ()'
    \'_   -   _'/  '
     | '-----' |   '

       _~^~^~_     '
  \)  /  o o  \  ()'
    \'_   -   _'/  '
     | '-----' |   '

       _~^~^~_     '
  \)  /  - -  \  ()'
    \'_   Y   _'/  '
     | '-----' |   '

       _~^~^~_     '
  ()  /  o o  \  (/'
    \'_   Y   _'/  '
     \ '-----' /   '

       _~^~^~_     '
  ()  /  o o  \  (/'
    \'_   y   _'/  '
     \ '-----' /   '

       _~^~^~_     '
  ()  /  o o  \  (/'
    \'_   y   _'/  '
     \ '-----' /   '
"; // end of FERRIS

For whichever image frames we wish to display, all we have to do is change the name of the constant in the println! statement. But let's do that via a variable:

main.rs
/* main.rs */

mod images;

use images::*;

fn main() {
  let model_str: &str = PLANE;
  println!("{}", D51model_str);
} // end of main()

Some of our images, such as D51, have multiple frames, and some, such as BOAT, don't. The more frames, the more/smoother "animation" is possible. But to work with multiple frames, it's more convenient if the image's string is broken down into its separate frames. In our original attempt, we had the frames stored in a vector, so that if there were four frames of an image, that image's variable was a vector containing four inner vectors, one inner vector per frame.

But when we moved that definition out of "main.rs" into its own file, "images.rs", that storage format became problematic, so we simplified the storage of an image's frames by putting all the frames into one &str-type of variable (a "constant", really).

Programming is always a trade-off. In this case, we made the storage and retrieval of the data simpler, but that simpler format makes the processing of the data a bit harder. We could have gone the other way and made the processing simpler, at the cost of making the storage and retrieval harder. We chose to make the storage and retrieval of the data easier. Now, to make the processing of the data easier, let's Convert The const To a Vector of Vectors.