Compare commits
9 Commits
4b16e30a79
...
dev
Author | SHA1 | Date | |
---|---|---|---|
d2b5b3da34 | |||
1af6779b0a | |||
a5161afd72 | |||
13afd17b91 | |||
998c1962b6 | |||
dcd042972c | |||
49087480b1 | |||
de9ec885c8 | |||
45d4d44d4c |
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= Cargo
|
||||
|
||||
@ -21,7 +21,7 @@ Bibliothek. +
|
||||
Es wird auch gleich `main.rs`, ein `.git`-Ordner (inkl. `.gitignore`)
|
||||
und `Cargo.toml` erstellt.
|
||||
|
||||
== Angelegte Datein
|
||||
== Angelegte Dateien
|
||||
|
||||
=== Cargo.toml
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= Erstes Spiel
|
||||
|
||||
@ -55,7 +55,7 @@ CLI-Eingabe
|
||||
** ohne die ``use'' Anweisung oben, müsste es `std::io::stdin()` sein
|
||||
* `.read_line(&mut guess)` ließt eine Zeile und speichert sie in guess
|
||||
** `&` erstellt dabei eine Referenz (wie in C)
|
||||
** Referenzen sind standardmäßig imutable - deshalb `&mut`
|
||||
** Referenzen sind standardmäßig immutable - deshalb `&mut`
|
||||
** `read_line()` gibt ein `Result`-Objekt zurück, dieser kann `Ok` oder
|
||||
`Err` enthalten
|
||||
* `.expect("Fehlermeldung")` entpackt das `Result`-Objekt
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= Konzepte
|
||||
|
||||
@ -71,7 +71,7 @@ fn main() {
|
||||
|
||||
Die Ausgabe des Programms ist dabei der letztere Wert, hier also 10.
|
||||
Es ist also mehr eine neue Variable unter dem selben Namen wie die alte.
|
||||
Sogar der Datentyp kann sich dabei ändern, man muss sich also nicht ständig neue Namen für Variabeln ausdenken, nur weil man sie casted (Juchuu!).
|
||||
Sogar der Datentyp kann sich dabei ändern, man muss sich also nicht ständig neue Namen für Variablen ausdenken, nur weil man sie casted (Juchuu!).
|
||||
|
||||
Da Variablen immer Block-Scope-basiert (?) sind, kann dies natürlich auch in einem eingebetteten Block genutzt werden.
|
||||
|
||||
@ -141,7 +141,7 @@ Chars werden mit single-quotes geschrieben (Strings mit doppelten quotes).
|
||||
|
||||
Allerdings scheint es noch ein wenig komplizierter zu sein, das kommt aber erst später.
|
||||
|
||||
=== Combound Types
|
||||
=== Compound Types
|
||||
Gruppierung von mehreren Werten in einem Typ.
|
||||
|
||||
==== Tupel
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= Ownership
|
||||
|
||||
@ -8,7 +8,7 @@ https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html[Link zum Buc
|
||||
== Was ist das?
|
||||
|
||||
Jeder Wert hat eine Variable, die ihn "besitzt".
|
||||
Jeder Wert kann zu einem Zeitpunkt nur von _einer_ Variable bessessen werden.
|
||||
Jeder Wert kann zu einem Zeitpunkt nur von _einer_ Variable besessen werden.
|
||||
Sollte die Variable aus dem Scope verschwinden, wird der Wert ungültig und aus dem Speicher entfernt.
|
||||
|
||||
== Warum?
|
||||
@ -148,4 +148,4 @@ Fun fact: String Literale sind auch Slices und damit Referenzen von Strings.
|
||||
Noch mehr fun fact: Da dynamische String und String Literale damit quasi den selben Typ beschreiben, haben sie auch den gemeinsamen Typ `&str`.
|
||||
Für Leseoperationen kann also im Allgemeinen dieser benutzt werden.
|
||||
|
||||
Slices können auch mutable sein, dafür muss aber das ursprüngliche Array mmutable sein und es kann immer nur ein mutable Slice gleichzetig existieren (also genauso wie beim Ownership).
|
||||
Slices können auch mutable sein, dafür muss aber das ursprüngliche Array mutable sein und es kann immer nur ein mutable Slice gleichzeitig existieren (also genauso wie beim Ownership).
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= Enums und Pattern Matching
|
||||
|
||||
@ -73,13 +73,13 @@ Es gibt zwar keine Attribute, aber da ja auch die internen Structs Methoden habe
|
||||
|
||||
Options hab ich oben schonmal kurz beschrieben.
|
||||
In Rust ist dieser Datentyp sehr wichtig.
|
||||
Die Dokumentation dazu ist https://doc.rust-lang.org/std/option/enum.Option.html[hier zu finden] und enthält sehr viel Wichtiges und Interesantes.
|
||||
Die Dokumentation dazu ist https://doc.rust-lang.org/std/option/enum.Option.html[hier zu finden] und enthält sehr viel Wichtiges und Interessantes.
|
||||
|
||||
== `match`
|
||||
|
||||
`match` ist quasi das `switch` von Rust.
|
||||
Nur kann es auch prüfen, ob eine Variable einem Enum-Typen angehört.
|
||||
So wie Rust bis jetzt klang, kann wahrscheinlich jedem Datentypen ein "match-Trait" gegeben werden, der dann eine "Zugehörigkeit" (Gleicheit stimmt ja irgendwie nicht) prüfen kann.
|
||||
So wie Rust bis jetzt klang, kann wahrscheinlich jedem Datentypen ein "match-Trait" gegeben werden, der dann eine "Zugehörigkeit" (Gleichheit stimmt ja irgendwie nicht) prüfen kann.
|
||||
|
||||
Aber ganz einfach: Angenommen wir wollen die Methode `to_css_string` von oben implementieren.
|
||||
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
|
||||
@ -124,7 +124,7 @@ Der Unterschied ist, dass bei `other` noch der Inhalt genutzt werden kann, bei `
|
||||
=== `if let`
|
||||
|
||||
Dieses if-Konstrukt nutzt man am besten, wenn man nur auf eine einzelne Variante eines Enums prüfen möchte.
|
||||
Letzendlich ist es ganz simpel:
|
||||
Letztendlich ist es ganz simpel:
|
||||
|
||||
[source, rust]
|
||||
----
|
||||
|
@ -1,10 +1,13 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-10-18T17:56:26+02:00
|
||||
|
||||
= How to: Projektmanagement
|
||||
|
||||
https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html[Link zum Buch]
|
||||
|
||||
== Packages, Crates, Modules, was?
|
||||
|
||||
Rust hat ein sehr hierachisches Konzept, was die Strukturierung von Projekten angeht.
|
||||
Rust hat ein sehr hierarchisches Konzept, was die Strukturierung von Projekten angeht.
|
||||
|
||||
Fangen wir mal von oben an:
|
||||
|
||||
@ -37,7 +40,7 @@ Ihr Merkmal ist vor allem, dass eine `main`-Funktion existiert, die der Einstieg
|
||||
|
||||
==== Library Crate
|
||||
|
||||
Wie der Name schon sagt, stellt diese Art Crate nur Funktionen zur verfügung wie eine Bibliothek.
|
||||
Wie der Name schon sagt, stellt diese Art Crate nur Funktionen zur Verfügung wie eine Bibliothek.
|
||||
|
||||
=== Modules
|
||||
|
||||
@ -143,7 +146,7 @@ fn main() {
|
||||
|
||||
Dagegen gilt für Enums: Wenn der Enum public ist, sind auch alle Varianten public.
|
||||
|
||||
==== Abürzungen mit `use`
|
||||
==== Abkürzungen mit `use`
|
||||
|
||||
Angenommen, wir haben eine Mediathek mit Filmen, Serien, Spielen, etc. und brauchen immer lange Zugriffspfade (also z.B. `crate::medien::spiele::liste::add()`), obwohl wir nur Spiele brauchen, kann `use` benutzt werden.
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||
|
||||
= Standard Collections
|
||||
|
||||
https://doc.rust-lang.org/book/ch08-00-common-collections.html[Link zum Buch]
|
||||
@ -141,7 +144,7 @@ Das macht das ganze ordentlich schwierig.
|
||||
|
||||
Ist immer eine schlechte Idee, außer man weiß exakt wie lang die einzelnen Zeichen (in Byte) des Strings sind.
|
||||
Im Englischen ist es normalerweise 1 Byte pro Zeichen, Umlaute sind schon 2, und so weiter.
|
||||
Sollte man außversehen ein Zeichen "durchschneiden" (also nur 1 Byte eines "ü" im Slice haben), gibt es eine Runtime Panic.
|
||||
Sollte man aus Versehen ein Zeichen "durchschneiden" (also nur 1 Byte eines "ü" im Slice haben), gibt es eine Runtime Panic.
|
||||
|
||||
=== Iterieren
|
||||
|
||||
@ -161,7 +164,7 @@ for b in "hallo".bytes() {
|
||||
// Wirft eben die einzelnen u8 raus.
|
||||
----
|
||||
|
||||
Wenn wir "grapheme" haben wollen (Was anscheinend sowas wie "volle Zeichen" sind, mehr als nur char), gibt es keine eingebaute Funktion aber crates, die das lösen.
|
||||
Wenn wir "grapheme" haben wollen (Was anscheinend so etwas wie "volle Zeichen" sind, mehr als nur char), gibt es keine eingebaute Funktion aber crates, die das lösen.
|
||||
|
||||
== HashMaps
|
||||
|
||||
@ -177,7 +180,7 @@ use std::collections::HashMap;
|
||||
|
||||
// -- Erstellen --
|
||||
// iter(), zip() und collect()
|
||||
// collect() kann in alles mögliche wandeln, deshalb muss der Typ anggeben werden.
|
||||
// collect() kann in alles mögliche wandeln, deshalb muss der Typ angegeben werden.
|
||||
let woerter = vec![String::from("eins"), String::from("zwei"), String::from("drei")];
|
||||
let zahlen = vec![1, 2, 3];
|
||||
let mut zahlwort: HashMap<_, _> = woerter.into_iter().zip(zahlen.into_iter()).collect();
|
||||
@ -216,6 +219,7 @@ Falls Key oder Value kein Copy Trait haben, wird der Ownership übergeben. Strin
|
||||
== Hausaufgaben
|
||||
|
||||
Das Buch gibt uns hier ein paar Aufgaben, die wir jetzt lösen können:
|
||||
|
||||
* Den Median aus einer Liste finden. Erst sortieren, dann den mittleren Wert.
|
||||
* Wörter zu "pig-latin" machen. Wenn erster Buchstabe ein Vokal ist, wird "-hay" angehängt, wenn es ein Konsonant ist, wird er ans Ende angefügt (nach "-") und "ay" angehängt.
|
||||
* Eine kleine Befehlszeile mit Befehlen wie "Add Name to Sales" und Ausgabe.
|
||||
|
104
diaries/rust/09 - Errors und panic.adoc
Normal file
104
diaries/rust/09 - Errors und panic.adoc
Normal file
@ -0,0 +1,104 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-22T17:04:01+02:00
|
||||
|
||||
= Errors und `panic!`
|
||||
|
||||
https://doc.rust-lang.org/book/ch09-00-error-handling.html[Link zum Buch]
|
||||
|
||||
== `panic!`
|
||||
|
||||
Dieses Makro it furchtbar simpel: Es macht Panik und das Programm stirbt mit einem Fehler.
|
||||
Diesen Fehler kann man auch nicht catchen.
|
||||
|
||||
Wenn `RUST_BACKTRACE` als Umgebungsvariable gesetzt ist, wird auch noch ein langer Traceback angezeigt, allerdings nur, solange Debug-Symbole aktiviert sind (also bei `cargo run` oder `cargo build` ohne `--release`).
|
||||
|
||||
Will man gar kein Traceback und kein "unwinding" (das "hochgehen" durch den Funktionsstack und Aufräumen), kann man auch noch folgendes zu seiner `Cargo.toml` hinzufügen:
|
||||
|
||||
[source, toml]
|
||||
----
|
||||
[profile.release]
|
||||
panic = 'abort'
|
||||
----
|
||||
|
||||
== `Result<T, E>`
|
||||
|
||||
Der Result-Datentyp ist deutlich besser für mögliche Fehler geeignet, die das Programm abfangen und bearbeiten kann.
|
||||
Falls zum Beispiel eine Datei auf dem Dateisystem nicht existiert, ist es ja manchmal gewünscht, dass diese Datei dann einfach angelegt wird.
|
||||
|
||||
Der `Result`-Typ ist ein Enum von `Ok<T>` und `Error<E>`.
|
||||
Also kann dann mit `match` geprüft werden, was genau wir gerade bekommen haben.
|
||||
Alternativ können auch Funktionen wie `unwrap_or_else(|error| {...})` genutzt werden.
|
||||
|
||||
`Ok<T>` verhält sich wie `Some<T>` und sollte zurückgegeben werden, wenn alles glatt läuft.
|
||||
|
||||
`Error<E>` beinhaltet einen Fehler.
|
||||
Der genaue Fehler kann mit `error.kind()` erfahren werden; ein weiteres `match` ist dann eine "genauere" Fehlerbehandlung.
|
||||
|
||||
Ein volles Beispiel mit ganz viel `match`:
|
||||
|
||||
[source, rust]
|
||||
----
|
||||
use std::fs::File;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
fn main() {
|
||||
let greeting_file_result = File::open("hello.txt");
|
||||
|
||||
let greeting_file = match greeting_file_result {
|
||||
Ok(file) => file,
|
||||
Err(error) => match error.kind() {
|
||||
ErrorKind::NotFound => match File::create("hello.txt") {
|
||||
Ok(fc) => fc,
|
||||
Err(e) => panic!("Problem creating the file: {:?}", e),
|
||||
},
|
||||
other_error => {
|
||||
panic!("Problem opening the file: {:?}", other_error);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
=== `unwrap()` und `expect()`
|
||||
|
||||
Machen aus einem `Result<T, E>` entweder ein `T` oder eine `panic!`.
|
||||
Bei `expect()` kann man noch die Fehlermeldung festlegen.
|
||||
|
||||
Warum man jemals `unwrap()` nehmen sollte, erschließt sich mir nicht ganz.
|
||||
|
||||
=== `?`
|
||||
|
||||
Oft schreibt man Funktionen so, dass Fehler weiter "hochgegeben" werden, falls man welche bekommt.
|
||||
`?` macht genau das bei einem Result.
|
||||
Codemäßig erklärt:
|
||||
|
||||
[source, rust]
|
||||
----
|
||||
let a = match result {
|
||||
Ok(nummer) => nummer,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
// Ergibt das selbe wie
|
||||
|
||||
let a = result?;
|
||||
----
|
||||
|
||||
Das `?` kann auch für zum Beispiel `Option` verwendet werden, dann returned es natürlich `None`.
|
||||
|
||||
=== Rückgaben von `main()`
|
||||
|
||||
Bis jetzt hat `main()` immer nichts, also implizit `()` zurückgegeben.
|
||||
Manchmal wollen wir ja aber auch was anderes als "0" als return code haben.
|
||||
Wir können Tatsächlich auch ein Result zurückgeben. Und zwar ein `Result<(), Box<dyn Error>>`.
|
||||
Der zweite Typ dort, kann wohl als "irgendein Fehler" gelesen werden und wird später noch erklärt.
|
||||
|
||||
Allgemein kann aber jedes Objekt, dass `std::process::Termination`-Trait implementiert von main als Rückgabe genutzt werden.
|
||||
|
||||
== Wann `Result<T, E>`, wann `panic!`?
|
||||
|
||||
Der Artikel ist sehr sehr sehr lang, aber eigentlich sagt er:
|
||||
"Panic nur wenn es eben nicht gerettet werden kann."
|
||||
Und obviously in Tests.
|
||||
|
||||
Und man kann natürlich auch tolle eigene Fehlertypen für Result bauen.
|
61
list.json
61
list.json
@ -1,19 +1,20 @@
|
||||
[
|
||||
{
|
||||
"type": "project",
|
||||
"name": "homepage",
|
||||
"short_desc": "This website.",
|
||||
"name": "terminal",
|
||||
"short_desc": "The terminal on my website.",
|
||||
"desc": [
|
||||
"This is my homepage.",
|
||||
"What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.",
|
||||
"Everyone else: Have no fear. It is pretty simple. You just type in commands and the output is shown here or it does something on the webite.",
|
||||
"To find out, which commands are available, you can type just %{help}.",
|
||||
"This is part of my homepage.",
|
||||
"What you see on the page resembles an CLI. You just type in commands and some output is shown or it does something on the website.",
|
||||
"To find out which commands are available, you can just type %{help}.",
|
||||
"",
|
||||
"Currently everything is still in development. So if you come back in a few days/weeks/months/years something could have been changed!",
|
||||
"Everything is always in development. So if you come back in a few days/weeks/months/years something could have been changed!",
|
||||
"You can also check out the #%{dev version|https://dev.c0ntroller.de} if you haven't already.",
|
||||
"",
|
||||
"Have fun!"
|
||||
],
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/frontpage"
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/frontpage",
|
||||
"title": "Terminal"
|
||||
},
|
||||
{
|
||||
"type": "project",
|
||||
@ -24,28 +25,31 @@
|
||||
"Then I created a webpage that fetches and shows various information.",
|
||||
"Currently it includes time, weather, calendar, departures and more."
|
||||
],
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/infoscreen"
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/infoscreen",
|
||||
"title": "Infoscreen"
|
||||
},
|
||||
{
|
||||
"type": "diary",
|
||||
"name": "rust",
|
||||
"short_desc": "Me learning Rust (German).",
|
||||
"desc": [
|
||||
"I documented my progress to lern the Rust programming language.",
|
||||
"I documented my progress to learn the Rust programming language.",
|
||||
"It follows the #%{Rust book|https://doc.rust-lang.org/book/} with my own annotations.",
|
||||
"Everything is in German as these notes are mostly meant for me."
|
||||
],
|
||||
"entries": [
|
||||
{ "title": "00 - Hello World", "filename": "00 - Hello World"},
|
||||
{ "title": "01 - Cargo", "filename": "01 - Cargo"},
|
||||
{ "title": "02 - Higher-Lower-Game", "filename": "02 - Higher-Lower-Spiel"},
|
||||
{ "title": "03 - Basics", "filename": "03 - Concepts"},
|
||||
{ "title": "04 - Ownership", "filename": "04 - Ownership"},
|
||||
{ "title": "05 - Structs", "filename": "05 - Structs"},
|
||||
{ "title": "06 - Enums", "filename": "06 - Enums"},
|
||||
{ "title": "07 - Crates & Modules", "filename": "07 - Management"},
|
||||
{ "title": "08 - Collections", "filename": "07 - Collections"}
|
||||
]
|
||||
{ "title": "Hello World", "filename": "00 - Hello World"},
|
||||
{ "title": "Cargo", "filename": "01 - Cargo"},
|
||||
{ "title": "Higher-Lower-Game", "filename": "02 - Higher-Lower-Spiel"},
|
||||
{ "title": "Basics", "filename": "03 - Concepts"},
|
||||
{ "title": "Ownership", "filename": "04 - Ownership"},
|
||||
{ "title": "Structs", "filename": "05 - Structs"},
|
||||
{ "title": "Enums", "filename": "06 - Enums"},
|
||||
{ "title": "Crates & Modules", "filename": "07 - Management"},
|
||||
{ "title": "Collections", "filename": "08 - Collections"},
|
||||
{ "title": "Errors und panic!", "filename": "09 - Errors und panic"}
|
||||
],
|
||||
"title": "Rust Diary"
|
||||
},
|
||||
{
|
||||
"type": "project",
|
||||
@ -53,10 +57,12 @@
|
||||
"short_desc": "TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
||||
"desc": [
|
||||
"TUfast is a browser extension that is used by multiple thousand users of the TU Dresden.",
|
||||
"It provides autologin to the most used portals, shortcuts, redirects, and more."
|
||||
"It provides autologin to the most used portals, shortcuts, redirects, and more.",
|
||||
"I'm one of the developers."
|
||||
],
|
||||
"repo": "https://github.com/TUfast-TUD/TUfast_TUD",
|
||||
"more": "https://tu-fast.de/"
|
||||
"more": "https://tu-fast.de/",
|
||||
"title": "TUfast TUD"
|
||||
},
|
||||
{
|
||||
"type": "project",
|
||||
@ -68,7 +74,8 @@
|
||||
"Even the self-hosted community version has no such functionality.",
|
||||
"I decided that's BS and made my own script to sync a project to git."
|
||||
],
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/overleaf-git-sync"
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/overleaf-git-sync",
|
||||
"title": "Overleaf Git Sync"
|
||||
},
|
||||
{
|
||||
"type": "project",
|
||||
@ -79,7 +86,8 @@
|
||||
"To get the initial tokens and the refresh token it is necessary to have a server that prints the POST body.",
|
||||
"This application does this."
|
||||
],
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server"
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server",
|
||||
"title": "Simple Callback Server"
|
||||
},
|
||||
{
|
||||
"type": "project",
|
||||
@ -87,9 +95,10 @@
|
||||
"short_desc": "A script that syncs a Google Photos album to your drive.",
|
||||
"desc": [
|
||||
"Giving random apps access to your Google Photos can be bad.",
|
||||
"To still use an album as screenaver etc. I wrote this script.",
|
||||
"To still use an album as screensaver etc. I wrote this script.",
|
||||
"It syncs all your photos to your drive while giving you maximum privacy."
|
||||
],
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server"
|
||||
"repo": "https://git.c0ntroller.de/c0ntroller/simple-callback-server",
|
||||
"title": "Photo Sync"
|
||||
}
|
||||
]
|
@ -39,9 +39,13 @@
|
||||
"repo": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"maxLength": 50
|
||||
}
|
||||
},
|
||||
"required": ["type", "name", "short_desc", "desc"]
|
||||
"required": ["type", "name", "short_desc", "desc", "title"]
|
||||
},
|
||||
"project": {
|
||||
"type": "object",
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-07-29T11:27:37+02:00
|
||||
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||
|
||||
= Overleaf Sync with Git
|
||||
|
||||
@ -43,7 +43,7 @@ But how to use them?
|
||||
|
||||
== Access granted
|
||||
|
||||
I noticed the front end uses session IDs for user authentification.
|
||||
I noticed the front end uses session IDs for user authentication.
|
||||
You get an ID, you POST valid credentials (and a CSRF token) to `/login` and your session ID get's "verified".
|
||||
|
||||
Using their repository, it was easy to find other routes that are useable.
|
||||
|
@ -1,5 +1,5 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-08T12:19:20+02:00
|
||||
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||
|
||||
= Simple Callback Server
|
||||
|
||||
@ -12,12 +12,12 @@ Still, I needed it sometimes and I didn't want to rewrite it every time I use it
|
||||
|
||||
== What can it be used for?
|
||||
|
||||
When creating a dev application on Google, Spotify, or other services you often have some heavy authentification flow to get access.
|
||||
When creating a dev application on Google, Spotify, or other services you often have some heavy authentication flow to get access.
|
||||
But normally I want to use the API for private projects and it's _my_ account that gets authenticated every time.
|
||||
|
||||
To make reauthentication easier these OAuth protocols often provide a "refresh token" which can be used to get a valid new token.
|
||||
|
||||
To get the initial authentification token and to get such a refresh token you provide a callback address where you get redirected after the user logs in.
|
||||
To get the initial authentication token and to get such a refresh token you provide a callback address where you get redirected after the user logs in.
|
||||
The tokens and meta information normally are sent in a `POST` body.
|
||||
And this is where this small application is necessary.
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
:experimental:
|
||||
:docdatetime: 2022-08-10T17:09:32+02:00
|
||||
:docdatetime: 2022-10-18T17:56:27+02:00
|
||||
|
||||
= c0ntroller.de
|
||||
= Terminal
|
||||
|
||||
Hello and welcome to my website.
|
||||
Hello and welcome to my CLI website.
|
||||
|
||||
== Why did I do this?
|
||||
Mainly because of boredom and because I like to code.
|
||||
@ -62,12 +62,12 @@ I talked about shortcuts before, but here's a list of which shortcuts are possib
|
||||
|kbd:[▲] / kbd:[▼]
|
||||
|Scroll through last commands.
|
||||
|
||||
|kbd:[Strg+L]
|
||||
|kbd:[Ctrl+L]
|
||||
|Clears the history. +
|
||||
Similar to `clear`.
|
||||
|
||||
|kbd:[Strg+D]
|
||||
|Exits the page. Don't work in (most?) cases because of a https://developer.mozilla.org/en-US/docs/Web/API/Window/close[JavaScript restriction]. +
|
||||
|kbd:[Ctrl+D]
|
||||
|Exits the page. If that doesn't work (https://developer.mozilla.org/en-US/docs/Web/API/Window/close[JavaScript restriction]) it goes back in page history. +
|
||||
Similar to `exit`.
|
||||
|
||||
|kbd:[Ctrl+U]/ +
|
||||
@ -82,8 +82,8 @@ kbd:[Ctrl+C]
|
||||
- Every line in the history window is parsed in a custom format.
|
||||
* `%{command}` is parsed to a clickable command
|
||||
* `#{link text|url}` is parsed to a link
|
||||
- Project logs are loaded dynamicly. They can be updated at any time.
|
||||
- There are lots of eastereggs. Some are for specfic people, some for me and some for fun.
|
||||
- Project logs are loaded dynamically. They can be updated at any time.
|
||||
- There are lots of eastereggs. Some are for specific people, some for me and some for fun.
|
||||
- I made some custom annotations for code blocks show faulty code (wrong syntax/will not compile/etc.).
|
||||
|
||||
[source.notCompiling, rust]
|
Reference in New Issue
Block a user