Erste Schritte mit Rust

Vor ein paar Tagen wollte ich die Programmiersprache Rust ausprobieren. Bei Rust handelt es sich um eine Sprache, welche syntaktisch stark an C angelehnt ist und besonderes Augenmerk auf Sicherheit legt. Die erste Frage, die sich mir stellte, ist, ob es für Rust, eine vernünftige IDE-Unterstützung existiert. Fündig geworden bin ich bei IntelliJ IDEA, welches nach Installation des Rust-Plugins zur Programmierung in der Sprache genutzt werden kann. Debugging von Rust-Programmen wird aus technischen Gründen nur in der JetBrains IDE CLion unterstützt, sodass hier einige Abstriche gemacht werden müssen. Neben der Rust-Integration für IntelliJ IDEA gibt es ebenfalls ein Plugin für Visual Studio Code, welches hier allerdings nicht weiter behandelt werden soll.

Mit dem passenden Plugin beherrscht IntelliJ IDEA Rust.

Neben der eigentlichen IDE wird Rust benötigt. Dieses kann über die offizielle Seite der Sprache bezogen werden. Nach der Installation kann in der IDE ein erstes Projekt angelegt werden. Anschließend findet sich in einem Ordner mit dem Namen src eine Datei mit dem Namen main.rs:

fn main() {
    println!("Hello, world!");
}

In dieser Datei findet sich ein minimales Hello world-Programm. Das Ausrufezeichen hinter dem println zeigt unter Rust an, das es sich um ein Makro handelt. Damit können Methoden und Makros einfach auseinander gehalten werden. Da ich Hello world-Programme immer etwas sinnfrei finde was das Lernen einer neuen Programmiersprache angeht, wollte ich für den ersten Versuch das Spiel Zahlenraten programmieren. Ziel des Spieles ist es eine Zahl zwischen 0 und 1000 zu erraten, welche der Rechner sich ausgedacht hat. Dazu muss im ersten Schritt eine Variable definiert werden, in welcher die zufällige Zahl gespeichert wird. Grundsätzlich sieht eine Variablendefinition und Deklaration unter Rust wie folgt aus:

let name: Typ = Wert;

Variablen in Rust sind immer Konstanten, wenn sie nicht explizit als veränderlich angegeben werden. Möglich ist dies mit dem Schlüsselwort mut:

let mut name: Typ = Wert;

Die Benennung von Variablen und anderen Elementen folgt in Rust einem bestimmten Schema. So werden Variablen snake_case benannt. Neben der Definition der Variable muss eine zufällige Zahl zwischen 0 und 1000 generiert werden. Dazu dient ein Zufallsgenerator, welcher über ein use eingebunden werden muss:

use rand::Rng;

Anschließend kann die Variable definiert und deklariert werden:

let number: u32 = rand::thread_rng().gen_range(0, 1000);

In diesem Fall wird ein vorzeichenloser Integer mit 32 Bit Breite als Datentyp definiert. Wird nun versucht das Rust-Programm zu kompilieren, so wird die Fehlermeldung:

error[E0432]: unresolved import `rand`
 --> src\main.rs:1:5
  |
1 | use rand::Rng;
  |     ^^^^ use of undeclared type or module `rand`

error[E0433]: failed to resolve: use of undeclared type or module `rand`
 --> src\main.rs:4:23
  |
4 |     let number: u32 = rand::thread_rng().gen_range(0, 1000);
  |                       ^^^^ use of undeclared type or module `rand`

error: aborting due to 2 previous errors

auftauchen. Grund hierfür ist, dass das genutzte Paket über den Paketmanager von Rust bezogen werden muss. Pakete werden über den Paketmanager Cargo bezogen. Die entsprechenden Pakete des offiziellen Repositorys sind unter crates.io zu finden. In der Datei Cargo.toml müssen die entsprechenden Abhängigkeiten eingebunden werden:

[dependencies]
rand = "0.7.3"
text_io = "0.1.8"

Neben dem Pseudozufallszahlengenerator, wurde gleich noch das Paket text_io eingebunden, welches später für die Eingabe von Text benötigt wird. Dieses Paket stellt hierbei das Makro read zur Verfügung, mit dessen Hilfe eine Eingabe realisiert werden kann:

let user_number: u32 = read!();

Damit sind die Grundlagen für das Spiel Zahlenraten gelegt und der Rest des Quellcodes ergibt praktisch sich von selbst:

use rand::Rng;
use text_io::read;

fn main() {

    let number: u32 = rand::thread_rng().gen_range(0, 1000);

    let mut running = true;

    println!("Ich habe mir eine Zahl zwischen 0 und 1000 ausgedacht.");

    while running {

        println!("Dein Vorschlag: ");
        let user_number: u32 = read!();

        if number > user_number {
            println!("Meine Zahl ist größer.");
        } else if number < user_number {
            println!("Meine Zahl ist kleiner.");
        } else {
            running = false;
        }
    }

    println!("Du hast die Zahl erraten. Es war die {}.", number);
}

Hervorzuheben ist, das unter Rust in if-Statements und Schleifen keine Klammern benötigt werden. Werden diese trotzdem genutzt, so warnt der Compiler entsprechend und bittet die überflüssigen Klammern zu entfernen.

Neben der entsprechenden Dokumentation auf der offiziellen Seite empfiehlt sich das Rust Cookbook als Quelle für die ersten Schritte unter Rust. Wer Rust einfach mal im Browser ausprobieren möchte, kann hierfür den Rust Playground nutzen.

Bookmarklet zum Sortieren von YouTube-Videos nach Dauer

Wird ein YouTube-Kanal geöffnet, so können die Videos in diesem nach der Beliebtheit und dem Datum sortiert werden. Eine Sortierung nach Dauer der Videos ist leider nicht vorgesehen. Abhilfe schafft ein entsprechendes Bookmarklet:

javascript:(function(){l=[].map.call(document.querySelectorAll("span.ytd-thumbnail-overlay-time-status-renderer"),function(e){l=e.innerHTML.trim().split(":").map(function(t){return parseInt(t)}).reduce(function(p,c){return p*60+c});return{a:e.parentElement.parentElement.parentElement,l:l}}).sort(function(a,b){return a.l-b.l});i=document.querySelector("#primary #items");l.forEach(function(o){i.appendChild(o.a.parentElement.parentElement.parentElement)})})()

Zum Anlegen des Bookmarklets muss ein neues Lesezeichen im Browser angelegt werden und der entsprechende JavaScript-Code in das Adressfeld des neuen Lesezeichens kopiert werden.

Nach der Nutzung des Bookmarklets sind die Videos nach Dauer sortiert

Zur Nutzung muss der entsprechende YouTube-Channel im Browser geöffnet sein und alle Videovorschaubilder, welche sortiert werden sollen, müssen geladen sein. Anschließend kann das Bookmarklet benutzt werden und alle Videos sind nach der Nutzung aufsteigend nach ihrer Länge sortiert.

Dark Mode auf Webseiten

In vielen Betriebssystemen wie z.B. macOS oder iOS zog in den letzten Versionen ein sogenannter Dark Mode ein. Bei diesem Modus werden die Elemente des Betriebssystems auf dunklere Farben eingestellt. Damit wird der Nutzer am Abend bzw. in der Dunkelheit nicht mehr so stark geblendet. Wird allerdings bei aktiviertem Dark Mode eine Webseite aufgerufen, welche von Haus aus mit hellen Farben arbeitet, so wird der Nutzer wieder geblendet. Mittlerweile können Webseiten sich allerdings dem gewünschten Farbschema anpassen. Dazu muss im CSS eine entsprechende Media Query definiert werden:

@media (prefers-color-scheme: dark) {
body {
    background-color: rgb(24, 26, 27);
    color: rgb(214, 211, 205);
}
}

Ist nun der Dark Mode im Betriebssystem aktiviert, wird das präferierte Farbschema übermittelt und kann dann CSS entsprechend umgesetzt werden.

seeseekey.net im Dark Mode

Wer die eigene Webseite mit einem dunklen Farbschema sehen möchte, kann dazu die Firefox-Erweiterung Dark Reader nutzen.

Dark Reader
Preis: Kostenlos

Mit dieser Erweiterungen können Webseiten automatisch in ihre dunklen Versionen überführt werden. Für die Entwicklung einer eigenen dunklen Variante können die neuen Farbwerte nun mittels der Entwicklertools des Browsers aus der Ausgabe der Erweiterung extrahiert werden.

Firefox Add-On zur Archivierung von Webseiten

Zur Archivierung von Webseiten existieren einige Lösungen. So z.B. die Nutzung der Archivierungsmöglichkeiten vom Internet Archive. In meinem Fall wollte ich allerdings, für eine Recherche, mehrere Webseiten lokal archivieren. Natürlich kann die Webseite über Browser eigenen Funktionalitäten gespeichert werden. Auch der Ausdruck bzw. die Generierung eines PDFs aus dem Ausdruck ist möglich. Wesentlich einfacher funktioniert die Archivierung von Webseiten mit dem Firefox Add-On SingleFile.

SingleFile
Preis: Kostenlos

Mit diesem Add-On ist es möglich eine Webseite in einer einzelnen HTML-Datei zu speichern. Bilder und andere Inhalte werden dabei in die HTML-Datei mit übernommen. Nach der Installation des Add-Ons kann über den entsprechenden Button einfach die Archivierung einer Webseite angestossen werden. Die erzeugte HTML-Datei wird dabei automatisch heruntergeladen.

Das Projekt auf GitHub

Die Erweiterung selbst wird auf GitHub entwickelt und ist unter der AGPL3 lizenziert. Damit handelt es sich bei der Erweiterung um freie Software. Neben der Firefox-Variante kann die Erweiterung auch unter Chrome genutzt werden.

Incremancer

Idle- bzw. Increment-Spiele, also Spiele die nebenbei ohne ständige Interaktion gespielt werden können gibt es mittlerweile seit ein paar Jahren. Meist werden diese Spiele im Browser gespielt. James Gittins hat ein solches Spiel unter dem Namen Incremancer entwickelt.

Incremancer in Aktion

In dem Spiel muss der Spieler mittels Zombies auf der Karte verteilte Dörfer angreifen, bis nur noch Zombies vorhanden sind. Von Level zu Level wird das Spiel hierbei schwerer und es müssen immer wieder neue Dinge erforscht und gebaut werden, um gegen Dorfbewohner zu bestehen. Zu finden ist Incremancer unter incremancer.gti.nz.