├── .gitignore ├── README.md ├── communication-material ├── de-DE │ └── greeting-email.md └── en-US │ └── greeting-email.md ├── courses ├── default.html └── default.md ├── example ├── c-lib │ ├── Cargo.toml │ ├── build.rs │ ├── include │ │ ├── core.h │ │ └── point.h │ ├── src │ │ └── lib.rs │ ├── test.sh │ └── test │ │ └── test.c └── tcp-mailbox │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Notes.md │ └── src │ ├── bin │ ├── simple.rs │ └── tokio.rs │ └── lib.rs └── presentation ├── .bowerrc ├── .gitignore ├── bower.json ├── chapters ├── de-DE │ ├── advanced-generics-bounds.chapter │ ├── basic-types.chapter │ ├── borrowing.chapter │ ├── cargo.chapter │ ├── closures.chapter │ ├── community-map.chapter │ ├── conversion-patterns.chapter │ ├── crates.chapter │ ├── data-structures.chapter │ ├── deref-coersions.chapter │ ├── documentation.chapter │ ├── drop-panic-abort.chapter │ ├── dynamic-and-static-libs.chapter │ ├── dynamic-dispatch.chapter │ ├── effective-rust.chapter │ ├── embedded.chapter │ ├── error-handling.chapter │ ├── ffi.chapter │ ├── functions.chapter │ ├── futures-and-tokio.chapter │ ├── generics-basics.chapter │ ├── imports-modules-and-visibility.chapter │ ├── inner-mutability.chapter │ ├── installation.chapter │ ├── intro.chapter │ ├── iterators-again.chapter │ ├── iterators.chapter │ ├── libcore-and-libstd.chapter │ ├── lifetimes.chapter │ ├── little-helpers.chapter │ ├── macros.chapter │ ├── match.chapter │ ├── memory-considerations.chapter │ ├── mutability.chapter │ ├── overview.chapter │ ├── ownership.chapter │ ├── send-and-sync.chapter │ ├── smart-pointers.chapter │ ├── stack-and-heap.chapter │ ├── standard-types.chapter │ ├── std-lib-tour.chapter │ ├── strings.chapter │ ├── testing.chapter │ ├── traits.chapter │ ├── unsafe.chapter │ ├── usage-examples.chapter │ └── working-with-nightly.chapter └── en-US │ ├── advanced-generics-bounds.chapter │ ├── borrowing.chapter │ ├── closures.chapter │ ├── conversion-patterns.chapter │ ├── crates.chapter │ ├── data-structures.chapter │ ├── deref-coersions.chapter │ ├── documentation.chapter │ ├── error-handling.chapter │ ├── functions.chapter │ ├── generics-basics.chapter │ ├── imports-modules-and-visibility.chapter │ ├── installation.chapter │ ├── intro.chapter │ ├── iterators.chapter │ ├── lifetimes.chapter │ ├── little-helpers.chapter │ ├── macros.chapter │ ├── match.chapter │ ├── memory-considerations.chapter │ ├── mutability.chapter │ ├── overview.chapter │ ├── ownership.chapter │ ├── send-and-sync.chapter │ ├── smart-pointers.chapter │ ├── standard-types.chapter │ ├── std-lib-tour.chapter │ ├── strings.chapter │ ├── testing.chapter │ ├── traits.chapter │ ├── usage-examples.chapter │ └── working-with-nightly.chapter ├── components ├── headjs │ ├── .bower.json │ ├── bower.json │ └── dist │ │ └── 1.0.0 │ │ ├── changelog.txt │ │ ├── head.core.js │ │ ├── head.core.min.js │ │ ├── head.core.min.js.map │ │ ├── head.css3.js │ │ ├── head.css3.min.js │ │ ├── head.css3.min.js.map │ │ ├── head.js │ │ ├── head.load.js │ │ ├── head.load.min.js │ │ ├── head.load.min.js.map │ │ ├── head.min.js │ │ └── head.min.js.map ├── jquery │ ├── .bower.json │ ├── MIT-LICENSE.txt │ ├── bower.json │ ├── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ └── src │ │ ├── ajax.js │ │ ├── ajax │ │ ├── jsonp.js │ │ ├── load.js │ │ ├── parseJSON.js │ │ ├── parseXML.js │ │ ├── script.js │ │ ├── var │ │ │ ├── nonce.js │ │ │ └── rquery.js │ │ └── xhr.js │ │ ├── attributes.js │ │ ├── attributes │ │ ├── attr.js │ │ ├── classes.js │ │ ├── prop.js │ │ ├── support.js │ │ └── val.js │ │ ├── callbacks.js │ │ ├── core.js │ │ ├── core │ │ ├── access.js │ │ ├── init.js │ │ ├── parseHTML.js │ │ ├── ready.js │ │ └── var │ │ │ └── rsingleTag.js │ │ ├── css.js │ │ ├── css │ │ ├── addGetHookIf.js │ │ ├── curCSS.js │ │ ├── defaultDisplay.js │ │ ├── hiddenVisibleSelectors.js │ │ ├── support.js │ │ ├── swap.js │ │ └── var │ │ │ ├── cssExpand.js │ │ │ ├── getStyles.js │ │ │ ├── isHidden.js │ │ │ ├── rmargin.js │ │ │ └── rnumnonpx.js │ │ ├── data.js │ │ ├── data │ │ ├── Data.js │ │ ├── accepts.js │ │ └── var │ │ │ ├── data_priv.js │ │ │ └── data_user.js │ │ ├── deferred.js │ │ ├── deprecated.js │ │ ├── dimensions.js │ │ ├── effects.js │ │ ├── effects │ │ ├── Tween.js │ │ └── animatedSelector.js │ │ ├── event.js │ │ ├── event │ │ ├── ajax.js │ │ ├── alias.js │ │ └── support.js │ │ ├── exports │ │ ├── amd.js │ │ └── global.js │ │ ├── intro.js │ │ ├── jquery.js │ │ ├── manipulation.js │ │ ├── manipulation │ │ ├── _evalUrl.js │ │ ├── support.js │ │ └── var │ │ │ └── rcheckableType.js │ │ ├── offset.js │ │ ├── outro.js │ │ ├── queue.js │ │ ├── queue │ │ └── delay.js │ │ ├── selector-native.js │ │ ├── selector-sizzle.js │ │ ├── selector.js │ │ ├── serialize.js │ │ ├── sizzle │ │ └── dist │ │ │ ├── sizzle.js │ │ │ ├── sizzle.min.js │ │ │ └── sizzle.min.map │ │ ├── traversing.js │ │ ├── traversing │ │ ├── findFilter.js │ │ └── var │ │ │ └── rneedsContext.js │ │ ├── var │ │ ├── arr.js │ │ ├── class2type.js │ │ ├── concat.js │ │ ├── hasOwn.js │ │ ├── indexOf.js │ │ ├── pnum.js │ │ ├── push.js │ │ ├── rnotwhite.js │ │ ├── slice.js │ │ ├── strundefined.js │ │ ├── support.js │ │ └── toString.js │ │ └── wrap.js └── reveal.js │ ├── .bower.json │ ├── CONTRIBUTING.md │ ├── Gruntfile.js │ ├── LICENSE │ ├── README.md │ ├── bower.json │ ├── css │ ├── print │ │ ├── paper.css │ │ └── pdf.css │ ├── reveal.css │ ├── reveal.scss │ └── theme │ │ ├── README.md │ │ ├── beige.css │ │ ├── black.css │ │ ├── blood.css │ │ ├── league.css │ │ ├── moon.css │ │ ├── night.css │ │ ├── serif.css │ │ ├── simple.css │ │ ├── sky.css │ │ ├── solarized.css │ │ ├── source │ │ ├── beige.scss │ │ ├── black.scss │ │ ├── blood.scss │ │ ├── league.scss │ │ ├── moon.scss │ │ ├── night.scss │ │ ├── serif.scss │ │ ├── simple.scss │ │ ├── sky.scss │ │ ├── solarized.scss │ │ └── white.scss │ │ ├── template │ │ ├── mixins.scss │ │ ├── settings.scss │ │ └── theme.scss │ │ └── white.css │ ├── demo.html │ ├── index.html │ ├── js │ └── reveal.js │ ├── lib │ ├── css │ │ └── zenburn.css │ ├── font │ │ ├── league-gothic │ │ │ ├── LICENSE │ │ │ ├── league-gothic.css │ │ │ ├── league-gothic.eot │ │ │ ├── league-gothic.ttf │ │ │ └── league-gothic.woff │ │ └── source-sans-pro │ │ │ ├── LICENSE │ │ │ ├── source-sans-pro-italic.eot │ │ │ ├── source-sans-pro-italic.ttf │ │ │ ├── source-sans-pro-italic.woff │ │ │ ├── source-sans-pro-regular.eot │ │ │ ├── source-sans-pro-regular.ttf │ │ │ ├── source-sans-pro-regular.woff │ │ │ ├── source-sans-pro-semibold.eot │ │ │ ├── source-sans-pro-semibold.ttf │ │ │ ├── source-sans-pro-semibold.woff │ │ │ ├── source-sans-pro-semibolditalic.eot │ │ │ ├── source-sans-pro-semibolditalic.ttf │ │ │ ├── source-sans-pro-semibolditalic.woff │ │ │ └── source-sans-pro.css │ └── js │ │ ├── classList.js │ │ ├── head.min.js │ │ └── html5shiv.js │ ├── package.json │ └── plugin │ ├── highlight │ └── highlight.js │ ├── markdown │ ├── example.html │ ├── example.md │ ├── markdown.js │ └── marked.js │ ├── math │ └── math.js │ ├── multiplex │ ├── client.js │ ├── index.js │ ├── master.js │ └── package.json │ ├── notes-server │ ├── client.js │ ├── index.js │ └── notes.html │ ├── notes │ ├── notes.html │ └── notes.js │ ├── print-pdf │ └── print-pdf.js │ ├── search │ └── search.js │ └── zoom-js │ └── zoom.js ├── css └── console.css ├── img └── rust.gif ├── index.html ├── js ├── em-artiste.js ├── locale-selector.js ├── playRust.js ├── remote-code.js ├── slideInit.js ├── svgDrawings.js └── url-search-params.js └── tasks ├── add-chapter.rsc ├── rename-chapter.rsc └── rename-chapters.rsc /.gitignore: -------------------------------------------------------------------------------- 1 | *target* 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Teach Rust 2 | 3 | "Teach Rust" is free workshop material to use to give a course introducing the Rust programming language. The time for the full course is around three to four days. 4 | 5 | The material is created with people with zero Rust experience but with a programming background in mind. 6 | 7 | ## Overview 8 | 9 | The course consists of two parts: 10 | 11 | [The course presentations](presentation) is used as an introduction into all basic aspects of Rust. It comes in small parts and ships with integration into the Rust playground for examples as well with a translation structure. 12 | 13 | [The work examples](example). The course constructs a small TCP server from ground up. 14 | 15 | Along with that, all communication material we used is supplied [here](communication-material). 16 | 17 | ## The presentations 18 | 19 | The presentation material is split into many small to medium presentations for every aspect of Rust. Not all are meant to fully cover a topic, but as an introduction of the important points. Chapters covering basic things such as ownership and borrowing should be exhaustive 20 | 21 | The presentations are Reveal presentations with plugins for internationalisation and integration into the [Rust Playground](https://play.rust-lang.org). 22 | 23 | The path through the presentations is not fixed, to allow leeway during holding the course. Examples of the pathes we used can be found in the [courses](courses) directory. We recommend to create your own while preparing for giving the workshop. 24 | 25 | ## The examples 26 | 27 | Currently, the course ships with three examples: 28 | 29 | * A simple TCP server that provides a very simple PUT and GET interface to store and remove messages 30 | * The same built with Tokio and Futures 31 | * A Rust library that can be used as a dynamic language 32 | 33 | The TCP server is meant to be built from ground up, starting with a fresh crate. 34 | 35 | The examples given here are an example of the final state. Before giving this course, you should develop this example by yourself. 36 | 37 | ## Open issues 38 | 39 | Currently, the largest issues are: 40 | 41 | * most of the course is in german and needs to be translated to english 42 | * the examples and the presentation lack READMEs 43 | 44 | ## Credits 45 | 46 | The development of this course was financed by [Asquera](https://asquera.de) for the courses given at [Linuxhotel](https://linuxhotel.de). 47 | 48 | They are open sourced as a contribution to the growth of the Rust language. 49 | 50 | If you want to fund further development of the course, book a training! 51 | 52 | ## Commercial use 53 | 54 | This course is expressively intended for commercial and free use. 55 | 56 | ## Trainers 57 | 58 | * [Florian Gilcher](https://asquera.de) 59 | * [Andrew Hobden](https://asquera.de) 60 | 61 | Want to be on this list: open an [issue](https://github.com/skade/rust-three-days-course/issues) and we will add you. 62 | 63 | ## License 64 | 65 | https://creativecommons.org/licenses/by-sa/4.0/ 66 | 67 | -------------------------------------------------------------------------------- /communication-material/de-DE/greeting-email.md: -------------------------------------------------------------------------------- 1 | Hallo, 2 | 3 | ich freue mich, Sie demnächst zu unserem Rust-Kurs begrüßen zu können. 4 | 5 | Wir werden uns drei Tage mit der Programmiersprache und dem Umfeld beschäftigen. Rust ist eine komplexe Programmiersprache - wir werden also nicht alles im Detail schaffen. Daher wird sich der Kurs auf gutes und sattelfestes Allgemeinwissen konzentrieren. Es ist auch Raum für komplexe Fragen vorgesehen. 6 | 7 | Sie werden nicht ohne Erwartungen an diesen Kurs ankommen und sicherlich einige Fragen haben, die Ihnen unter den Nägeln brennen. Genauso bin ich ganz gespannt, was denn denn alles ist. 8 | 9 | Daher möchte ich Sie bitten, sich in Vorbereitung auf den Kurs kurz mit folgenden Fragen zu beschäftigen: 10 | 11 | * Wofür möchte ich Rust einsetzen? 12 | * Welche Frage(n) wollte ich schon immer mal beantwortet haben? 13 | * Wenn Sie bereits mit Rust gearbeitet haben: was ist ihnen schwer gefallen? 14 | * Mit welcher der folgenden Sprachen würden Sie sich am meisten identifizieren? 15 | - C/C++ 16 | - Objective-C/Swift 17 | - Haskell/ML 18 | - Ruby/Python/Perl/Java 19 | 20 | Wir werden diese Fragen am Anfang des Kurses in der Gruppe besprechen, sie helfen mir dabei, in den folgenden Tagen besser auf sie einzugehen. 21 | 22 | Am Ende möchte ich Sie bitten, alle Fragen und Wünsche möglichst früh zu äussern. Ich weiss auch nicht immer alles mit einem Beispiel aus dem Hinterkopf, je früher ich Bescheid weiss, umso mehr Zeit habe ich, diese Frage in den Folgetagen zu beantworten. 23 | 24 | Mit besten Grüßen, -------------------------------------------------------------------------------- /communication-material/en-US/greeting-email.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/communication-material/en-US/greeting-email.md -------------------------------------------------------------------------------- /example/c-lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "core" 3 | version = "0.1.0" 4 | authors = ["Florian Gilcher "] 5 | 6 | build = "build.rs" 7 | 8 | [dependencies] 9 | libc = "0.2.14" 10 | 11 | [build-dependencies] 12 | rusty-cheddar = "0.3.0" 13 | 14 | [lib] 15 | crate-type = ["dylib", "staticlib"] -------------------------------------------------------------------------------- /example/c-lib/build.rs: -------------------------------------------------------------------------------- 1 | extern crate cheddar; 2 | 3 | fn main() { 4 | cheddar::Cheddar::new().expect("could not read manifest") 5 | .run_build("include/point.h"); 6 | } 7 | -------------------------------------------------------------------------------- /example/c-lib/include/core.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef cheddar_generated_core_h 3 | #define cheddar_generated_core_h 4 | 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | typedef struct Point { 16 | int32_t x; 17 | int32_t y; 18 | } Point; 19 | 20 | Point* new_point(int32_t x, int32_t y); 21 | 22 | void destroy_point(Point* p); 23 | 24 | void inspect(Point* p); 25 | 26 | 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /example/c-lib/include/point.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef cheddar_generated_point_h 3 | #define cheddar_generated_point_h 4 | 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | typedef struct Point { 16 | int32_t x; 17 | int32_t y; 18 | } Point; 19 | 20 | Point* new_point(int32_t x, int32_t y); 21 | 22 | void destroy_point(Point* p); 23 | 24 | void inspect_point(Point* p); 25 | 26 | 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /example/c-lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | #[repr(C)] 3 | pub struct Point { 4 | x: i32, 5 | y: i32 6 | } 7 | 8 | #[no_mangle] 9 | pub extern "C" fn new_point(x: i32, y: i32) -> *mut Point { 10 | let p = Box::new(Point { x: x, y: y }); 11 | Box::into_raw(p) 12 | } 13 | 14 | #[no_mangle] 15 | pub extern "C" fn destroy_point(p: *mut Point) { 16 | let _: Box = unsafe { Box::from_raw(p) }; 17 | } 18 | 19 | #[no_mangle] 20 | pub extern "C" fn inspect_point(p: *mut Point) { 21 | unsafe { 22 | let point: Box = Box::from_raw(p); 23 | println!("{:?}", point); 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /example/c-lib/test.sh: -------------------------------------------------------------------------------- 1 | gcc -L target/debug/ -I include -lc -lm -lSystem -lcore test/test.c -o point 2 | -------------------------------------------------------------------------------- /example/c-lib/test/test.c: -------------------------------------------------------------------------------- 1 | #include "../include/point.h" 2 | 3 | int main (int argc, char const *argv[]) 4 | { 5 | Point* p = new_point(1,1); 6 | inspect_point(p); 7 | p->x = 2; 8 | inspect_point(p); 9 | } 10 | -------------------------------------------------------------------------------- /example/tcp-mailbox/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tcp-mailbox" 3 | version = "0.1.0" 4 | authors = ["Florian Gilcher "] 5 | 6 | [dependencies] 7 | futures = "0.1" 8 | tokio-core = "0.1" 9 | tokio-service = "0.1" 10 | tokio-proto = "0.1" 11 | clap = "2.20" 12 | -------------------------------------------------------------------------------- /example/tcp-mailbox/Notes.md: -------------------------------------------------------------------------------- 1 | # Code example 2 | 3 | ## First day 4 | 5 | First day: write a single-threaded TCP-Server wrapping a VecDeque. 6 | 7 | Implement the protocol as a library. 8 | 9 | -------------------------------------------------------------------------------- /example/tcp-mailbox/src/bin/simple.rs: -------------------------------------------------------------------------------- 1 | use std::net::{TcpListener, TcpStream}; 2 | use std::io::BufReader; 3 | use std::io::BufRead; 4 | use std::io::Write; 5 | use std::thread; 6 | use std::sync::{Arc, Mutex}; 7 | 8 | struct SyncedMailbox { 9 | inner: Mutex>, 10 | } 11 | 12 | impl SyncedMailbox { 13 | fn new() -> SyncedMailbox { 14 | let inner = Mutex::new(Vec::new()); 15 | SyncedMailbox { inner: inner } 16 | } 17 | 18 | fn write(&self, message: String) { 19 | let mut vector = self.inner.lock().unwrap(); 20 | vector.push(message); 21 | } 22 | 23 | fn read(&self) -> Option { 24 | let mut vector = self.inner.lock().unwrap(); 25 | vector.pop() 26 | } 27 | } 28 | 29 | fn main() { 30 | let listener = TcpListener::bind("127.0.0.1:7200").unwrap(); 31 | 32 | let storage = Arc::new(SyncedMailbox::new()); 33 | 34 | for stream in listener.incoming() { 35 | match stream { 36 | Ok(mut s) => { 37 | let local_storage = storage.clone(); 38 | thread::spawn(move || { 39 | handle(&mut s, &local_storage); 40 | }); 41 | } 42 | Err(e) => { 43 | println!("A connection failed. Error: {}", e); 44 | } 45 | } 46 | } 47 | } 48 | 49 | fn handle(stream: &mut TcpStream, storage: &SyncedMailbox) { 50 | let message = read_message(stream); 51 | match message.trim() { 52 | "READ" => { 53 | handle_read(stream, storage); 54 | } 55 | _ => { 56 | handle_write(message, storage); 57 | } 58 | } 59 | } 60 | 61 | fn handle_read(stream: &mut TcpStream, storage: &SyncedMailbox) { 62 | let data = storage.read(); 63 | 64 | match data { 65 | Some(message) => write!(stream, "{}", message), 66 | None => write!(stream, "No message in inbox!\n") 67 | }.ok().expect("Write failed!"); 68 | } 69 | 70 | fn handle_write(message: String, storage: &SyncedMailbox) { 71 | storage.write(message); 72 | } 73 | 74 | fn read_message(stream: &mut TcpStream) -> String { 75 | let mut read_buffer = String::new(); 76 | let mut buffered_stream = BufReader::new(stream); 77 | let res = buffered_stream.read_line(&mut read_buffer); 78 | res.ok().expect("An error occured while reading!"); 79 | read_buffer 80 | } 81 | -------------------------------------------------------------------------------- /example/tcp-mailbox/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Mutex; 2 | use std::collections::VecDeque; 3 | 4 | pub struct SyncedMailbox { 5 | inner: Mutex>, 6 | } 7 | 8 | impl SyncedMailbox { 9 | pub fn new() -> SyncedMailbox { 10 | let inner = Mutex::new(VecDeque::new()); 11 | SyncedMailbox { inner: inner } 12 | } 13 | 14 | pub fn write(&self, message: String) { 15 | let mut vector = self.inner.lock().unwrap(); 16 | vector.push_back(message); 17 | } 18 | 19 | pub fn read(&self) -> Option { 20 | let mut vector = self.inner.lock().unwrap(); 21 | vector.pop_front() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /presentation/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "components" 3 | } -------------------------------------------------------------------------------- /presentation/.gitignore: -------------------------------------------------------------------------------- 1 | nbproject/ 2 | -------------------------------------------------------------------------------- /presentation/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cviewer", 3 | "version": "0.0.1", 4 | "description": "Rust Presentation on reveal", 5 | "license": "GNU GPL2", 6 | "dependencies": { 7 | "jquery": "~2.1.4", 8 | "reveal.js": "*" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/basic-types.chapter: -------------------------------------------------------------------------------- 1 | # Basistypen 2 | 3 | --- 4 | 5 | ## ints 6 | 7 | Rust liefert die Standard-Int-Typen mit, jeweils mit und ohne Vorzeichen. 8 | 9 | * i8, u8 10 | * i16, u16 11 | * i32, u32 12 | * i64, u64 13 | * i128, u128 (bald) 14 | 15 | --- 16 | 17 | ## Architekturabhängige Zahlen 18 | 19 | Rust hat 2 architekturabhängige Zahlentypen: 20 | 21 | * isize, usize 22 | 23 | --- 24 | 25 | ## Casts 26 | 27 | Casts zwischen den Typen sind möglich, _auch verkürzende Casts_: 28 | 29 | ```rust 30 | fn main() { 31 | let foo = 3i64; 32 | let bar = foo as i32; 33 | } 34 | ``` 35 | 36 | --- 37 | 38 | Falls die Breite nicht angegeben wird, oder inferiert werden kann, ist `i32` Standard. 39 | 40 | --- 41 | 42 | ## Überlauf-Verhalten 43 | 44 | Überläufe Rust lösen im Debug-Modus eine Trap aus, im Release-Modus nicht! 45 | 46 | --- 47 | 48 | ## Floats 49 | 50 | Genauso liefert Rust Gleitkommazahlen aller Größen: f8, f16, f32, f64 51 | 52 | ```rust 53 | fn main() { 54 | let float: f64 = 1f; 55 | } 56 | ``` 57 | 58 | --- 59 | 60 | ## Arrays 61 | 62 | Arrays fixer Größe haben folgende Notation: 63 | 64 | ```rust 65 | fn main() { 66 | let arr: [i32; 4] = [1,2,3,4]; 67 | } 68 | ``` 69 | 70 | --- 71 | 72 | ## Arrays dynamischer Größe 73 | 74 | Arrays dynamischer Größe müssen in Rust als Slice abgebildet werden. 75 | 76 | Slices tragen einen Pointer auf einen Array und eine Länge. Slices können weder vergrößert noch verkleinert werden. 77 | 78 | ```rust 79 | fn main() { 80 | let arr: &[i32] = &[1,2,3,4]; 81 | } 82 | ``` 83 | 84 | --- 85 | 86 | ## Der Unit-Type 87 | 88 | Ausdrücke die keine Rückgabe haben, geben den Unit-Type zurück. 89 | 90 | ```rust 91 | fn main() -> () { 92 | 42; 93 | } 94 | ``` -------------------------------------------------------------------------------- /presentation/chapters/de-DE/closures.chapter: -------------------------------------------------------------------------------- 1 | # Closures 2 | 3 | Rust hat Closures. Mehrere. 4 | 5 | --- 6 | 7 | 8 | Vorteil: 9 | * Hoch optimiert und nur mit den absolut benötigten Laufzeitkosten. 10 | 11 | Nachteil: 12 | * Den Typ zu bestimmen ist nicht immer einfach 13 | 14 | --- 15 | 16 | ## Notation 17 | 18 | ```rust 19 | fn main() { 20 | let vec = vec![1,2,3]; 21 | vec.map(|x| x**2).collect::>(); 22 | } 23 | ``` 24 | 25 | ```rust 26 | fn main() { 27 | let vec = vec![1,2,3]; 28 | let double = |x| { x ** 2 }; 29 | vec.map(double).collect::>(); 30 | } 31 | ``` 32 | 33 | --- 34 | 35 | ## Closure-Typen 36 | 37 | FnOnce 38 | * Die Closure konsumiert ihre Umgebung 39 | FnMut 40 | * Die Closure verändert ihre Umgebung 41 | Fn 42 | * Die Closure referenziert ihre Umgebung immutabel 43 | 44 | --- 45 | 46 | `rustc` stellt den Typ automatisch fest, aber man braucht ihn in Typsignaturen! 47 | 48 | --- 49 | 50 | Es besteht eine Typbeziehung: Fn impliziert FnMut, FnMut impliziert FnOnce. 51 | 52 | --- 53 | 54 | ## Notation von Closure-Argumenten 55 | 56 | ```rust 57 | fn call_with_one(some_closure: F) -> i32 58 | where F: Fn(i32) -> i32 { 59 | 60 | some_closure(1) 61 | } 62 | ``` 63 | 64 | --- 65 | 66 | ## Moves und Closures 67 | 68 | Da die Closure-Umgebung implizit ist, müssen Werte explizit hineinbewegt werden. 69 | 70 | ```rust 71 | fn main() { 72 | let num = 5; 73 | 74 | let owns_num = move |x: i32| x + num; 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/community-map.chapter: -------------------------------------------------------------------------------- 1 | # Die Rust-Community 2 | 3 | --- 4 | 5 | Wo Hilfe und Ansprache finden? 6 | 7 | --- 8 | 9 | ## Generell 10 | 11 | Eine Mail an `community-team@rust-lang.org` ist nie falsch. 12 | 13 | --- 14 | 15 | ## Teams 16 | 17 | * Core 18 | * Language 19 | * Libraries 20 | * Compiler 21 | * Tooling 22 | * Community 23 | * Documentation 24 | * Moderation 25 | * Style 26 | 27 | --- 28 | 29 | ## Webseiten 30 | 31 | * [https://rust-lang.org](https://rust-lang.org) 32 | * [https://community.rs](https://community.rs) 33 | * [URLO users.rust-lang.org](https://users.rust-lang.org) 34 | * [IRLO internals.rust-lang.org](https://internals.rust-lang.org) 35 | * Semi-offiziell: Reddit /r/rust 36 | 37 | [Code of Conduct](https://www.rust-lang.org/en-US/conduct.html) 38 | 39 | --- 40 | 41 | ## IRC 42 | 43 | `irc.mozilla.org`: 44 | 45 | * `#rust` 46 | * `#rust-beginners` 47 | * `#rust-embedded` 48 | * `#rust-community` 49 | * `#rust-docs` 50 | 51 | --- 52 | 53 | ## Für Produktionsuser 54 | 55 | * Regelmässige Surveys durch das Projektteam 56 | * Regelmässige Interviews durch das Projektteam 57 | 58 | --- 59 | 60 | ## Änderungen 61 | 62 | Änderungen an der Sprache und Stdbibliothek benötigen einen RFC: 63 | 64 | * [RFCS](https://github.com/rust-lang/rfcs) 65 | 66 | --- 67 | 68 | ## Konferenzen 69 | 70 | * RustConf 71 | * RustFest 72 | * Rust Belt Rust 73 | 74 | --- 75 | 76 | ## Am Ball bleiben 77 | 78 | * [Community Calendar]( https://calendar.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc@group.calendar.google.com) 79 | * [TWIR - This Week in Rust](https://this-week-in-rust.org/) 80 | * Und viele andere "this week in"-Newsletter 81 | 82 | --- 83 | 84 | ## Beitragen 85 | 86 | * `rustc` hat eine durchschnittliche Verweildauer von Patches von 6 Tagen(!). 87 | * Kleinere Fixes, gerade Dokufixes werden täglich gemerged. 88 | * Homu und Highfive freuen sich auf Sie! -------------------------------------------------------------------------------- /presentation/chapters/de-DE/conversion-patterns.chapter: -------------------------------------------------------------------------------- 1 | # Konvertierungen 2 | 3 | Rust bietet viele Möglichkeiten, die Konvertierung eines Typs in einen anderen auszudrücken. 4 | 5 | Das erhöht die Sicherheit und kommunziert den Zweck. 6 | 7 | --- 8 | 9 | ## `From`, `Into` 10 | 11 | Konvertierung eines Typens in einen anderen. 12 | 13 | Ist `X` `From`, dann ist `T` automatisch `Into`. 14 | 15 | Die Verwendung hängt vom Kontext ab. 16 | 17 | --- 18 | 19 | ## Beispiel 20 | 21 | ```rust 22 | fn main() { 23 | let string = String::from("string slice"); 24 | let string2: String = "string slice".into(); 25 | } 26 | ``` 27 | 28 | --- 29 | 30 | ## Was macht eigentlich `try!` oder `?` genau? 31 | 32 | ```rust 33 | use std::io; 34 | use std::fs::File; 35 | use std::io::prelude::*; 36 | 37 | enum MyError { 38 | FileWriteError 39 | } 40 | 41 | impl From for MyError { 42 | fn from(e: io::Error) -> MyError { 43 | MyError::FileWriteError 44 | } 45 | } 46 | 47 | fn write_to_file_using_try() -> Result<(), MyError> { 48 | let mut file = try!(File::create("my_best_friends.txt")); 49 | try!(file.write_all(b"This is a list of my best friends.")); 50 | println!("I wrote to the file"); 51 | Ok(()) 52 | } 53 | // This is equivalent to: 54 | fn write_to_file_using_match() -> Result<(), MyError> { 55 | let mut file = try!(File::create("my_best_friends.txt")); 56 | match file.write_all(b"This is a list of my best friends.") { 57 | Ok(v) => v, 58 | Err(e) => return Err(From::from(e)), 59 | } 60 | println!("I wrote to the file"); 61 | Ok(()) 62 | } 63 | ``` 64 | 65 | --- 66 | 67 | ## `AsRef` 68 | 69 | Referenz-zu-Referenz-Konvertierung. Zeigt an, dass ein Typ einfach Referenzen auf andere Typen produzieren kann. 70 | 71 | --- 72 | 73 | ## Beispiel 74 | 75 | ```rust 76 | fn main() { 77 | open_file("test"); 78 | let path_buf = PathBuf::from("test"); 79 | open_file(path_buf); 80 | } 81 | 82 | fn open_file>(p: &P) { 83 | let path = p.as_ref(); 84 | let file = File::open(path); 85 | } 86 | ``` 87 | 88 | --- 89 | 90 | ## `Borrow` und `BorrowMut` 91 | 92 | `Borrow` abstrahiert über Ownership und Borrowing. `Borrow` bedeutet, dass der Typ einen Borrow des Typen `T` erzeugen kann. Es ist ähnlich `AsRef`, kommuniziert aber einem anderen Zweck. 93 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/crates.chapter: -------------------------------------------------------------------------------- 1 | # Crates 2 | 3 | Rust nennt Bibliotheken "crates". Management von Bibliotheken mit `cargo` ist üblich, aber nicht notwendig. 4 | 5 | --- 6 | 7 | ## Einbindung von Bibliotheken 8 | 9 | Bibliotheken werden durch das `extern crate`-statement eingebunden. 10 | 11 | ```rust 12 | extern crate serde; 13 | extern crate serde_json; 14 | 15 | fn main() { 16 | use serde_json::Value; 17 | 18 | let data = r#" { "name": "John Doe", "age": 43, ... } "#; 19 | let v: Value = serde_json::from_str(data)?; 20 | println!("Please call {} at the number {}", v["name"], v["phones"][0]); 21 | } 22 | ``` 23 | 24 | Dies importiert das "SERialisation/DEserialisation"-Framework. 25 | 26 | --- 27 | 28 | ## Einbinden von Macros 29 | 30 | Da Macros immer global für die gesamte Bibliothek gelten, müssen sie folgendermaßen eingebunden werden: 31 | 32 | ``` 33 | #[macro_use] extern crate serde_macros; 34 | ``` 35 | 36 | Dies importiert die Macro-Sätze von serde, die die Arbeit stark vereinfachen. 37 | 38 | --- 39 | 40 | Crates können wie normale use-statements umbenannt werden: 41 | 42 | ```rust 43 | extern crate serde_json as json; 44 | ``` 45 | 46 | --- 47 | 48 | ## crates.io 49 | 50 | Veröffentlichte Bibliotheken finden sich auf [crates.io](https://crates.io), ihre Dokumentation wird automatisch auf [docs.rs](https://docs.rs) veröffentlicht. 51 | 52 | --- 53 | 54 | ## Crates und Programme 55 | 56 | `cargo install my_crate` installiert die ausführbaren Programme einer Crate. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/data-structures.chapter: -------------------------------------------------------------------------------- 1 | # Datenstrukturen 2 | 3 | --- 4 | 5 | ## Structs 6 | 7 | --- 8 | 9 | ## Definition 10 | 11 | ```rust 12 | struct Point { 13 | x: i32, 14 | y: i32, 15 | } 16 | ``` 17 | 18 | --- 19 | 20 | ## Allokation 21 | 22 | ```rust 23 | struct Point { 24 | x: i32, 25 | y: i32, 26 | } 27 | 28 | fn main() { 29 | let p = Point { x: 1, y: 1 }; 30 | } 31 | ``` 32 | 33 | --- 34 | 35 | ## Feldzugriff 36 | 37 | ```rust 38 | struct Point { 39 | x: i32, 40 | y: i32, 41 | } 42 | 43 | fn main() { 44 | let p = Point { x: 1, y: 2 }; 45 | println!("{}", p.x); 46 | println!("{}", p.y); 47 | } 48 | ``` 49 | 50 | --- 51 | 52 | ## Structs ohne Felder 53 | 54 | Structs müssen keine Felder haben. 55 | 56 | ```rust 57 | struct TCPProtocol; 58 | 59 | fn main() { 60 | let proto = TCPProtocol; 61 | } 62 | ``` 63 | 64 | Diese Structs haben zur Laufzeit keine Größe. 65 | 66 | --- 67 | 68 | ## Tupel 69 | 70 | ```rust 71 | fn main() { 72 | let p = (1, 2); 73 | println!("{}", p.0); 74 | println!("{}", p.1); 75 | } 76 | ``` 77 | 78 | --- 79 | 80 | ## Benannte Tupel ("tuple structs") 81 | 82 | ```rust 83 | struct Point(i32,i32); 84 | 85 | fn main() { 86 | let p = Point(1, 2); 87 | println!("{}", p.0); 88 | println!("{}", p.1); 89 | } 90 | ``` 91 | 92 | --- 93 | 94 | ## Enums 95 | 96 | ```rust 97 | enum Direction { 98 | Right, 99 | Left, 100 | Up, 101 | Down, 102 | } 103 | 104 | fn main() { 105 | let direction = Direction::Left; 106 | } 107 | ``` 108 | 109 | Die einzelnen Ausformungen von Enums heissen "Variante". 110 | 111 | --- 112 | 113 | ## Enums mit Werten 114 | 115 | ```rust 116 | enum Movement { 117 | Right(i32), 118 | Left(i32), 119 | Up(i32), 120 | Down(i32), 121 | } 122 | 123 | fn main() { 124 | let movement = Movement::Left(12); 125 | } 126 | ``` 127 | 128 | --- 129 | 130 | ## Enums mit strukturierten Varianten 131 | 132 | ```rust 133 | enum Actions { 134 | StickAround, 135 | MoveTo { x: i32, y: i32}, 136 | } 137 | 138 | fn main() { 139 | let action = Actions::MoveTo { x: 0, y: 0 }; 140 | } 141 | ``` 142 | 143 | --- 144 | 145 | ## Enums ohne Varianten 146 | 147 | ```rust 148 | enum ExternalType {}; 149 | ``` 150 | 151 | Enums ohne Varianten haben keine Speichergröße und können nicht in Rust erstellt werden. Sie eignen sich daher zum Einsatz im FFI, dazu später mehr. 152 | 153 | --- 154 | 155 | ## Sind Varianten Typen? 156 | 157 | Nein. Momentan(!) nicht. 158 | 159 | --- 160 | 161 | ## `null` 162 | 163 | Gibts nicht. 164 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/deref-coersions.chapter: -------------------------------------------------------------------------------- 1 | # Deref-Conversions 2 | 3 | --- 4 | 5 | ## Motivation 6 | 7 | Warum funktioniert eigentlich folgendes? 8 | 9 | ```rust 10 | struct Point { 11 | x: i32, 12 | y: i32 13 | } 14 | 15 | fn main() { 16 | let boxed_p = Box::new(Point { x: i32, y: i32 }); 17 | println!("{}", boxed_p.x); 18 | } 19 | ``` 20 | 21 | Box hat doch garkein Feld "x"! 22 | 23 | --- 24 | 25 | ## Auto-Dereferenzierungen 26 | 27 | Rust dereferenziert unter bestimmten Umständen automatisch. Wie alles andere, muss das explizit angefordert werden über: 28 | 29 | * Einen Aufruf oder Feldzugriff via den `.`-Operator 30 | * Eine explizite Dereferenzierung mit `*` 31 | * Bei der Übergabe mit `&` 32 | * Führt manchmal zu einem hässlichen `&*`-Pattern 33 | 34 | --- 35 | 36 | Dies macht vor allem Wrapper-Typen sehr ergonomisch! 37 | 38 | --- 39 | 40 | Dahinter stecken die `Deref` und `DerefMut`-Traits. 41 | 42 | ```rust 43 | impl Deref for Box { 44 | type Target = T; 45 | 46 | fn deref(&self) -> &T { 47 | self.inner 48 | } 49 | } 50 | ``` 51 | 52 | Dieser Aufruf wird eingefügt, wenn Dereferenzierungen angefordert werden. 53 | 54 | --- 55 | 56 | ## Wichtige Auto-Dereferenzierungen 57 | 58 | * String -> &str 59 | * Vec -> &[T] 60 | 61 | Funktionen, die immutabel auf Strings oder Vektoren arbeiten, sollten eine immutable Slice als Argument verwenden. Das Layout der Typen ist so gewählt, dass das _kostenfrei_ ist. 62 | 63 | --- 64 | 65 | ```rust 66 | fn print_me(message: &str) { println!("{}", message); } 67 | 68 | fn main() { 69 | print_me("Foo"); 70 | let a_string = String::from("Bar"); 71 | print_me(&a_string); 72 | print_me(a_string.as_str()) 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/documentation.chapter: -------------------------------------------------------------------------------- 1 | # Dokumentation 2 | 3 | --- 4 | 5 | ## `rustdoc` 6 | 7 | Rust bietet ein Standarddokumentationswerkzeug namens `rustdoc`. Es wird häufig durch `cargo doc` verwendet. 8 | 9 | Deshalb ist Rust-Code fast immer in einem gemeinsamen Format dokumentiert. 10 | 11 | --- 12 | 13 | ## `std` Dokumentation 14 | 15 | Die Standard-Bibliotheksdokumentation wird unter https://doc.rust-lang.org/std/ gehostet. 16 | 17 | Eine lokale Offline-Version kann geöffnet werden mit: 18 | 19 | ```bash 20 | rustup doc --std 21 | ``` 22 | 23 | --- 24 | 25 | ## Crate Dokumentation 26 | 27 | Dokumentation für Crates unter http://crates.io/ finden Sie unter https://docs.rs/. 28 | 29 | Einige Crates können auch andere Dokumente über den Link "Dokumentation" auf ihrer Liste in http://crates.io/ gefunden haben. 30 | 31 | --- 32 | 33 | ## Beispiel: Ein Modul 34 | 35 | 36 | 37 | --- 38 | 39 | ## Beispiel: Ein Modul 40 | 41 | Diese Seite dokumentiert das `vec` Modul. 42 | 43 | Es beginnt mit einigen Beispielen, dann listet alle `struct`s, Eigenschaften oder Funktionen, die das Modul exportiert. 44 | 45 | --- 46 | 47 | ## Wie wird es generiert? 48 | 49 | `rustdoc` kann Rust-Code und Markdown-Dokumente lesen. 50 | 51 | `//!` Und `///` Kommentare werden als Markdown gelesen. 52 | 53 | ```rust 54 | //! Moduldokumentationskommentare wie der Abschnitt 'Examples' von `std::vec`. 55 | 56 | /// Dokumente Funktionen, `struct`s und Eigenschaften. 57 | /// Hier wird eine Funktion dokumentiert 58 | fn function_with_documentation() {} 59 | 60 | // Dieser Kommentar wird nicht als Dokumentation angezeigt. 61 | // Die Funktion wird noch angezeigt. 62 | fn function_without_documentation() {} 63 | ``` 64 | 65 | --- 66 | 67 | ## Beispiel: Komponenten 68 | 69 | 70 | 71 | --- 72 | 73 | ## Beispiel: Funktionen 74 | 75 | 76 | 77 | --- 78 | 79 | ## Codebeispiele 80 | 81 | Standardmäßig werden Codeblöcke in der Dokumentation getestet. 82 | 83 |

 84 | /// ```rust
 85 | /// assert_eq!(always_true(), true)
 86 | /// ```
 87 | fn always_true() -> bool { true }
 88 | 
89 | 90 | --- 91 | 92 | ## Navigation 93 | 94 | Die Argumente und Rückgabetypen von Funktionen sind Links zu ihren jeweiligen Typen. 95 | 96 | Die Seitenleiste auf der linken Seite bietet eine schnelle Navigation zu anderen Teilen des Moduls. 97 | 98 | --- 99 | 100 | ## Trait-Implementerungen 101 | 102 | Bei Trait-Implementierungen wird die Dokumentation mit in den Code gezogen, genauso wie alle Funktionen, die durch `Deref` erreichbar sind. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/drop-panic-abort.chapter: -------------------------------------------------------------------------------- 1 | # Drop, panic und abort 2 | 3 | Was passiert eigentlich genau, wenn wir Typen droppen? 4 | 5 | --- 6 | 7 | ## Drop-Reihenfolge 8 | 9 | Die Drop-Reihenfolge in Rust ist momentan _nicht_ standardisiert. Es gibt jedoch gute Gründe, sie so zu standardisieren, wie sie gerade ist. 10 | 11 | [Diskussion](https://github.com/rust-lang/rfcs/issues/1857) 12 | 13 | --- 14 | 15 | ## Drop-Reihenfolge 16 | 17 | * Werte werden fallen gelassen, wenn ihr Scope zuende ist 18 | * Die Reihenfolge ist _genau umgekehrt wie ihre Einführung_ 19 | * Nicht gebundene Werte droppen _sofort_ 20 | 21 | --- 22 | 23 | ## Destruktoren 24 | 25 | Manchmal müssen vor der Deallokation bestimmte Aktionen ausgeführt werden. 26 | 27 | Hierzu kann der Trait `Drop` implementiert werden. 28 | 29 | --- 30 | 31 | ```rust 32 | struct LevelDB { 33 | handle: *leveldb_database_t 34 | } 35 | 36 | impl Drop for LevelDB { 37 | fn drop(&self) { 38 | unsafe { leveldb_close(self.handle) }; 39 | } 40 | } 41 | ``` 42 | 43 | --- 44 | 45 | ## Vorsicht! 46 | 47 | Destruktoren können keine Fehler zurückgeben. 48 | 49 | --- 50 | 51 | ## Auch möglich 52 | 53 | Explizite Löschung des Werts durch eine konsumierende Funktion. Dies kann (momentan) nicht erzwungen werden. 54 | 55 | --- 56 | 57 | ## Panics 58 | 59 | Rust besitzt einen weiteren Fehlermechanismus: `panic!` 60 | 61 | ```rust 62 | fn main() { 63 | panicing_function(); 64 | } 65 | 66 | fn panicing_function() { 67 | panic!("gosh, don't call me!"); 68 | } 69 | ``` 70 | 71 | --- 72 | 73 | Im Falle einer Panic passiert Folgendes: 74 | * Der Thread hält sofort an 75 | * Der Stack wird aufgerollt 76 | * Alle von der Panic betroffenen Werte werden fallengelassen 77 | 78 | --- 79 | 80 | Panics gleichen mechanisch C++-Exceptions, sollten aber nur zur Behandlung schlimmer Fehler verwendet werden. Sie können nicht (normalerweise) gefangen werden. 81 | 82 | Der betroffene Thread stellt die Arbeit ein. 83 | 84 | --- 85 | 86 | ## Das Fangen von Panics 87 | 88 | Panics über FFI-Grenzen hinweg sind undefiniertes Verhalten. Daher gibt es Fälle, in denen sie aus Rust heraus gefangen werden sollten: hierzu gibt es [std::panic::catch-unwind](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) und [std::panic::resume-unwind](https://doc.rust-lang.org/std/panic/fn.resume_unwind.html). 89 | 90 | --- 91 | 92 | ## Hooks 93 | 94 | [std::panic::set_hook](https://doc.rust-lang.org/std/panic/fn.set_hook.html) erlaubt einen Handler zu setzen, der _vor_ der Behandlung der Panic ausgeführt wird. 95 | 96 | --- 97 | 98 | Generell sollte _immer_ `Result` verwendet werden. 99 | 100 | --- 101 | 102 | ## Abort 103 | 104 | In manchen Umgebungen macht panic! keinen Sinn. In diesem Fall besitzen `rustc` und `cargo` einen Schalter, mit dem `panic!` einen sofortigen Programmabbruch hervorruft. 105 | 106 | Der Panic-Hook wird ausgeführt. 107 | 108 | --- 109 | 110 | ## Doppelte Panics 111 | 112 | Sollte beim behandeln einer panic innerhalb eines Threads eine weitere Auftreten (z.B. beim Ausführen eines Destruktors), tritt undefiniertes Verhalten auf und das Programm bricht sofort ab. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/dynamic-and-static-libs.chapter: -------------------------------------------------------------------------------- 1 | # Dynamische und statische Bibliotheken 2 | 3 | --- 4 | 5 | Einmal umgekehrt: Rust aus C verwenden. 6 | 7 | --- 8 | 9 | ## Bibliothek 10 | 11 | ```rust 12 | #[derive(Debug)] 13 | #[repr(C)] 14 | pub struct Point { 15 | x: i32, 16 | y: i32 17 | } 18 | 19 | #[no_mangle] 20 | pub extern "C" fn new_point(x: i32, y: i32) -> *mut Point { 21 | let p = Box::new(Point { x: x, y: y }); 22 | Box::into_raw(p) 23 | } 24 | 25 | #[no_mangle] 26 | pub extern "C" fn destroy_point(p: *mut Point) { 27 | let _: Box = unsafe { Box::from_raw(p) }; 28 | } 29 | 30 | #[no_mangle] 31 | pub extern "C" fn inspect_point(p: *mut Point) { 32 | unsafe { 33 | let point: Box = Box::from_raw(p); 34 | point.inspect(); 35 | }; 36 | } 37 | ``` 38 | 39 | --- 40 | 41 | ## C-Header (Auszug) 42 | 43 | ```c 44 | #include 45 | #include 46 | 47 | typedef struct Point { 48 | int32_t x; 49 | int32_t y; 50 | } Point; 51 | 52 | Point* new_point(int32_t x, int32_t y); 53 | 54 | void destroy_point(Point* p); 55 | 56 | void inspect(Point* p); 57 | ``` 58 | 59 | --- 60 | 61 | ## Cargo 62 | 63 | ```toml 64 | [lib] 65 | crate-type = ["dylib", "staticlib"] 66 | ``` 67 | 68 | `cargo build` baut nun statt einer rlib eine dynamische und eine statische lib. 69 | 70 | --- 71 | 72 | ## Verwendung 73 | 74 | ```c 75 | #include "../include/point.h" 76 | 77 | int main (int argc, char const *argv[]) 78 | { 79 | Point* p = new_point(1,1); 80 | inspect_point(p); 81 | p->x = 2; 82 | inspect_point(p); 83 | destroy_point(p); 84 | } 85 | ``` 86 | 87 | ```sh 88 | gcc -L target/debug/ -I include -lc -lm -lSystem -lcore test/test.c -o point 89 | ``` 90 | 91 | --- 92 | 93 | ## Ausführen 94 | 95 | ```sh 96 | $ ./point 97 | Point { x: 1, y: 1 } 98 | Point { x: 2, y: 1 } 99 | point(98132,0x7fffb30293c0) malloc: *** error for object 0x7fa635c02980: pointer being freed was not allocated 100 | *** set a breakpoint in malloc_error_break to debug 101 | Abort trap: 6 102 | ``` 103 | 104 | --- 105 | 106 | ## Woops! 107 | 108 | Passen Sie gut mit Ownership auf! 109 | 110 | ```rust 111 | #[no_mangle] 112 | pub extern "C" fn inspect_point(p: *mut Point) { 113 | unsafe { 114 | let point: Box = Box::from_raw(p); 115 | point.inspect(); 116 | std::mem::forget(point); 117 | }; 118 | } 119 | ``` 120 | 121 | --- 122 | 123 | ## Helfer 124 | 125 | * Cheddar - generiert C-Header von Rust-Libs. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/dynamic-dispatch.chapter: -------------------------------------------------------------------------------- 1 | # Dynamischer Dispatch 2 | 3 | Manchmal möchte man sich zur Laufzeit für eine Code-Implementierung verlassen, statt den Compiler monomorphieren zu lassen. 4 | 5 | Hierzu gibt es 2 Möglichkeiten. 6 | 7 | --- 8 | 9 | ## Dispatch durch Enums 10 | 11 | Wenn die Anzahl der Möglichkeiten beschränkt ist, kann gerne zu einem Enum gegriffen werden: 12 | 13 | ```rust 14 | enum Operation { 15 | Get, 16 | Set(String), 17 | Count 18 | } 19 | 20 | fn execute(op: Operation) { 21 | match op { 22 | Operation::Get => execute_get(), 23 | Operation::Set(s) => execute_set(s), 24 | Operation::Count => execute_count() 25 | } 26 | } 27 | ``` 28 | 29 | --- 30 | 31 | ## Alternative Form 32 | 33 | ```rust 34 | 35 | ```rust 36 | enum Operation { 37 | Get, 38 | Set(String), 39 | Count 40 | } 41 | 42 | impl Operation { 43 | fn execute(&self) { 44 | match &self { 45 | &Operation::Get => execute_get(), 46 | &Operation::Set(s) => execute_set(s), 47 | &Operation::Count => execute_count() 48 | } 49 | } 50 | } 51 | ``` 52 | 53 | 54 | --- 55 | 56 | ## Hinweis 57 | 58 | Verhindern Sie wiederholtes matchen auf denselben Enum, wenn nicht unbedingt notwendig. 59 | 60 | --- 61 | 62 | ## Trait-Objekte 63 | 64 | Referenzen oder rohe Pointer auf Traits, genauso wie Boxen, beschreiben sogenannte "Trait-Objekte". 65 | 66 | Trait-Objekte sind ein Paar von Pointern auf eine virtuelle Funktionstabelle und die konkreten Daten. 67 | 68 | --- 69 | 70 | ## Einschränkungen 71 | 72 | * Es kann nur ein Trait pro Objekt verwendet werden 73 | * Dieser Trait muss bestimmten Regeln gehorchen 74 | 75 | --- 76 | 77 | ## Regeln für Objekt-Traits 78 | 79 | * Objektsichere Traits dürfen _nicht_ `Self: Sized` verlangen 80 | * Alle Methoden sind objektsicher 81 | - sie haben keine Typ-Parameter 82 | - sie verwnden nicht `Self` 83 | 84 | --- 85 | 86 | ## Weitere Eigenschaften 87 | 88 | * Da Trait-Objekte den Objekt-Typ zur Laufzeit halten, unterstützen sie Downcasts. 89 | 90 | ```rust 91 | use std::fmt::Debug; 92 | use std::any::Any; 93 | 94 | // Logger function for any type that implements Debug. 95 | fn log(value: &T) { 96 | let value_any = value as &Any; 97 | 98 | // try to convert our value to a String. If successful, we want to 99 | // output the String's length as well as its value. If not, it's a 100 | // different type: just print it out unadorned. 101 | match value_any.downcast_ref::() { 102 | Some(as_string) => { 103 | println!("String ({}): {}", as_string.len(), as_string); 104 | } 105 | None => { 106 | println!("{:?}", value); 107 | } 108 | } 109 | } 110 | ``` 111 | 112 | --- 113 | 114 | ## Trait Objects und Closures 115 | 116 | Da Closures Traits implementieren, sind sie legale Trait-Objekte. 117 | 118 | ```rust 119 | fn factory() -> Box i32> { 120 | let num = 5; 121 | 122 | Box::new(move |x| x + num) 123 | } 124 | ``` -------------------------------------------------------------------------------- /presentation/chapters/de-DE/effective-rust.chapter: -------------------------------------------------------------------------------- 1 | # Effizientes Rust 2 | 3 | --- 4 | 5 | ## Iteratoren 6 | 7 | Sie sollten sich an die Iterator-API gewöhnen und sie verwenden. 8 | 9 | Iteratoren werden stark über kombinierte Operation hinweg optimiert. 10 | 11 | --- 12 | 13 | ## Eigenheiten durch Ownership 14 | 15 | Das Herausbewegen von Daten aus Kollektionen ist in Rust nicht möglich. Zumindest nicht, ohne einen Wert dort zu hinterlassen. 16 | 17 | Indiana Jones verwendet `std::mem::swap` oder `std::mem::replace`. 18 | 19 | --- 20 | 21 | In manchen Fällen hilft hier "Drain", ein Iterator, der Werte Stück für Stück aus einer Kollektion ableitet und sie dabei verkleinert. 22 | 23 | 24 | --- 25 | 26 | ## Kompilierzeiten 27 | 28 | `rustc` ist nicht der schnellste Compiler, aber es werden viel Zeit in der Codegenerierung und Optimierung durch LLVM verbracht. 29 | 30 | `cargo check` führt nur die Typprüfung von Rust aus und übersetzt den Code nicht. 31 | 32 | Unterteilen des Projekts in mehrere Crates kann auch helfen, da Crates nur bei Änderung kompiliert werden. 33 | 34 | Gehen Sie vorsichtiger mit Generics um. 35 | 36 | --- 37 | 38 | ## Binärgröße senken 39 | 40 | * System-Allokator verwenden (nightly feature) 41 | * Wird libstd kaum verwenden, kann sie ersetzt werden 42 | * Anzahl der monomorphisierten Funktionen senken 43 | 44 | --- 45 | 46 | ## Richtig konvertieren 47 | 48 | Das "Durchschleifen" von generischen Parametern ist zu vermeiden, wenn diese zu etwas konkretem evaluiert werden können. 49 | 50 | ```rust 51 | pub fn first_layer_of_indirection>(p: P) { 52 | something_using_the_path(p); 53 | } 54 | 55 | fn something_using_the_path>(p: P) { 56 | //.... 57 | } 58 | ``` 59 | 60 | --- 61 | 62 | ```rust 63 | #[inline] 64 | pub fn first_layer_of_indirection>(p: P) { 65 | let path = p.as_ref(); 66 | something_using_the_path(path); 67 | } 68 | 69 | fn something_using_the_path(p: Path) { 70 | //.... 71 | } 72 | ``` 73 | 74 | Rust inlined über Bibliotheksgrenzen hinweg. 75 | 76 | --- 77 | 78 | ## Helfer 79 | 80 | * Debugging: moderne GDB-Versionen unterstützen Rust 81 | * valgrind 82 | * rust-afl erlaubt Fuzzing mit American Fuzzy Lop 83 | * TODO: Code Coverage 84 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/embedded.chapter: -------------------------------------------------------------------------------- 1 | # Eingebettete Systeme in Rust 2 | 3 | --- 4 | 5 | ## Anlaufstellen 6 | 7 | [http://www.rust-embedded.org/](http://www.rust-embedded.org/) 8 | 9 | --- 10 | 11 | ## Stack 12 | 13 | Xargo: Cross-kompilierung mit libcore und libstd: 14 | [https://github.com/japaric/xargo](https://github.com/japaric/xargo) 15 | 16 | Cross: Cross-Testing der Resultate mit QEMU 17 | [https://github.com/japaric/cross](https://github.com/japaric/cross) 18 | 19 | --- 20 | 21 | ## Lesestoff 22 | 23 | Discovery: Discovering microcontrollers through Rust. 24 | 25 | [https://github.com/japaric/discovery](https://github.com/japaric/discovery) 26 | 27 | Copper: Microcontroller programmieren mit Rust und Cortex-M. 28 | 29 | [https://japaric.github.io/copper/](https://japaric.github.io/copper/) 30 | 31 | --- 32 | 33 | ## Projekte 34 | 35 | Tock, ein Betriebssystem für Cortex-M-Prozessoren: [tockos.org](tockos.org) 36 | 37 | --- 38 | 39 | ## Probleme 40 | 41 | * LLVM-Target-Support 42 | - LLVM war bisher gut auf Platformen, auf denen Apple unterwegs ist 43 | - Das heisst nicht, das LLVM in irgendeiner Art feindlich wäre! 44 | * Ungelöste Ansätze in Rust, insbesondere Bitfields 45 | * Inline-Assembly und ähnliches ist instabil 46 | * Core-Entwickler sind Desktop- und Serverentwickler und haben wenig Erfahrung 47 | - "Lieber erstmal garnicht, als schlecht!" 48 | * Wir brauchen hier unbedingt Vendor-buy-in 49 | 50 | --- 51 | 52 | ## Lösung 53 | 54 | * Rust ist eine treibende Kraft hinter besserem Target-Support in LLVM 55 | - Mehrere Targets, unter anderem AVR, unterwegs in den nächsten Versionen 56 | * Enthusiastische Embedded-Community 57 | * Rust hat einen sehr guten Community-Prozess für Features, die Core nicht lösen kann 58 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/error-handling.chapter: -------------------------------------------------------------------------------- 1 | # Fehlerbehandlung 2 | 3 | --- 4 | 5 | Fehlerbehandlung in Rust ist explizit. 6 | 7 | Eine Funktion, die bekannte Fehlerbedingungen hat, gibt einen Wert vom Typ `Result` zurück. 8 | 9 | **Es gibt keine Ausnahmebehandlung.** 10 | 11 | --- 12 | 13 | ```rust 14 | fn this_can_fail(succeeds: bool) -> Result { 15 | if succeeds { 16 | Ok(String::from("Es funktionierte!")) 17 | } else { 18 | Err(String::from("Es hat nicht funktioniert!")) 19 | } 20 | } 21 | 22 | fn main() { 23 | let outcome = this_can_fail(true); 24 | } 25 | ``` 26 | 27 | --- 28 | 29 | ## Ergebnisse müssen verwendet werden 30 | 31 | ``` 32 | warning: unused variable: `outcome`, #[warn(unused_variables)] on by default 33 | --> :10:9 34 | | 35 | 10 | let outcome = this_can_fail(true); 36 | | ^^^^^^^ 37 | ``` 38 | 39 | --- 40 | 41 | ## Ergebnisse verwenden mit `match` 42 | 43 | ```rust 44 | fn main() { 45 | match this_can_fail(false) { 46 | Ok(val) => println!("Funktioniert: {}", val), 47 | Err(err) => println!("Gescheitert: {}", err), 48 | } 49 | } 50 | ``` 51 | 52 | --- 53 | 54 | ## Verwenden von Ergebnissen mit Bedingungen 55 | 56 | Auf Erfolg prüfen mit `is_ok()`, Fehler mit `is_err()`: 57 | 58 | ```rust 59 | fn main() { 60 | if this_can_fail(false).is_ok() { 61 | println!("It worked!"); 62 | } else { 63 | println!("It didn't work!") 64 | } 65 | } 66 | ``` 67 | 68 | --- 69 | 70 | ## Ergebnisse mit `?` verwenden 71 | 72 | `?` eignet sich für Funktionen mit mehreren möglichen Fehlerpunkten. 73 | 74 | ```rust 75 | fn multiple_possible_failures() -> Result { 76 | this_can_fail(true)?; 77 | println!("Nach dem ersten Fehler"); 78 | this_can_fail(false)?; 79 | println!("Nach dem zweiten potentiellen Fehler"); 80 | Ok(String::from("Alles erledigt")) 81 | } 82 | 83 | fn main() { 84 | multiple_possible_failures(); 85 | } 86 | ``` 87 | 88 | --- 89 | 90 | ## Ergebnisse mit `?` verwenden 91 | 92 | Ausgabe: 93 | 94 | ``` 95 | Nach dem ersten Ausfall 96 | ``` 97 | 98 | Beachten Sie die vorzeitige Rückkehr. 99 | 100 | --- 101 | 102 | In früheren Rust-Versionen wurde statt `?` der `try!` Macro-Macro verwendet. 103 | 104 | --- 105 | 106 | ## Ergebnisse sind Wrappertypen 107 | 108 | Es ist möglich, ein `Result` in ein `Result` zu ändern, ohne es zu entpacken. 109 | 110 | Das Transformieren eines `Result` in ein `Result` ist ebenfalls möglich. 111 | 112 |
113 | +-----+   +-----+   +-----+
114 | | T,E |-->| U,E |-->| U,X |
115 | +-----+   +-----+   +-----+
116 | 
117 | 118 | --- 119 | 120 | ## Ergebniswerte umwandeln 121 | 122 | ```rust 123 | fn main() { 124 | let some_result = this_can_fail(true); 125 | // Dies wird nur ausgeführt, wenn `some_result` eine `Ok`-Variante ist. 126 | let mapped_result = some_result.map(|val| val.len()); 127 | println!("{:?}", mapped_result); 128 | } 129 | ``` 130 | 131 | `map_err()` ist ebenfalls verfügbar. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/functions.chapter: -------------------------------------------------------------------------------- 1 | # Funktionen 2 | 3 | --- 4 | 5 | ## Deklaration 6 | 7 | ```rust 8 | fn add(first: i32, second: i32) -> i32 { 9 | first + second 10 | } 11 | ``` 12 | 13 | --- 14 | 15 | ## Rückgabewert 16 | 17 | der Rückgabewert ist optional. 18 | 19 | ```rust 20 | fn return_nothing() {} 21 | 22 | fn return_a_random() -> i32 { 23 | 4 // Garantiert zufällig, gewählt durch Würfelwurf 24 | } 25 | 26 | fn maybe_return_a_random(should: bool) -> Option { 27 | if should { Some(4) } else { None } 28 | } 29 | ``` 30 | 31 | --- 32 | 33 | Signaturen müssen immer vollständig sein! 34 | 35 | --- 36 | 37 | Funktionen sind auch Werte (in Form eines Funktionspointers), dazu später mehr. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/futures-and-tokio.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/de-DE/futures-and-tokio.chapter -------------------------------------------------------------------------------- /presentation/chapters/de-DE/generics-basics.chapter: -------------------------------------------------------------------------------- 1 | # Simple Generics 2 | 3 | --- 4 | 5 | Generics sind fundamental für Rust. 6 | 7 | --- 8 | 9 | ## Generische Structs 10 | 11 | ```rust 12 | struct Point { 13 | x: Precision, 14 | y: Precision 15 | } 16 | 17 | fn main() { 18 | let point = Point { x: 1u32, y: 2 }; 19 | let point: Point = Point { x: 1, y: 2 }; 20 | } 21 | ``` 22 | 23 | --- 24 | 25 | ## Typinferenz 26 | 27 | Rust findet bei ausreichender Informationslage selbst 28 | die Typen aller Variablen und Generics heraus. 29 | 30 | Dies gilt nur _innerhalb_ von Funktionsgrenzen. 31 | 32 | Signaturen müssen immer voll angegeben werden. 33 | 34 | --- 35 | 36 | ## Generische Enums 37 | 38 | ```rust 39 | enum Either { 40 | Left(T), 41 | Right(X) 42 | } 43 | 44 | fn main() { 45 | let alternative: Either = Either::Left(i32); 46 | } 47 | ``` 48 | 49 | --- 50 | 51 | ## Wichtige generische Enums 52 | 53 | --- 54 | 55 | ## Option 56 | 57 | ```rust 58 | enum Option { 59 | Some(T), 60 | None 61 | } 62 | 63 | fn main() { 64 | let args = std::os::args; 65 | println!("{:?} {:?}", args.at(0), args.at(1)) 66 | } 67 | ``` 68 | 69 | Beschreibt einen Wert, der nicht zwingend vorhanden sein muss. 70 | 71 | `None` ist ein Wert, sollte als nicht mit `null` verwechselt werden. 72 | 73 | --- 74 | 75 | ## Result 76 | 77 | ```rust 78 | enum Result { 79 | Ok(T), 80 | Err(E) 81 | } 82 | 83 | fn main() { 84 | let file = std::fs::File::open("I don't exist!"); 85 | println!("{:?}", file); 86 | } 87 | ``` 88 | 89 | Beschreibt, ob eine Operation erfolgreich war und gibt entweder 90 | den Wert oder einen Fehlerwert zurück. 91 | 92 | --- 93 | 94 | ## Typische Results 95 | 96 | ```rust 97 | Result<(), io::Error> 98 | Result 99 | Result 100 | ``` 101 | 102 | --- 103 | 104 | ## Generische Funktionen 105 | 106 | Generische Funktionen haben Typparameter. 107 | 108 | ```rust 109 | fn accept_any_type(arg: T) { 110 | // ... 111 | } 112 | 113 | fn transmute(arg: T) -> U { 114 | // ... 115 | } 116 | ``` 117 | 118 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/inner-mutability.chapter: -------------------------------------------------------------------------------- 1 | # Innere Mutabilität 2 | 3 | TODO: Cover that in a future course with more advanced subjects -------------------------------------------------------------------------------- /presentation/chapters/de-DE/installation.chapter: -------------------------------------------------------------------------------- 1 | # Die Toolchain 2 | 3 | Florian Gilcher 4 | 5 | --- 6 | 7 | https://www.rust-lang.org/en-US/install.html 8 | 9 | --- 10 | 11 | ## Rustup 12 | 13 | Rustup ist das Standard-Tool zum Managen von Rusts compiler-Toolchain. 14 | 15 | http://rustup.rs/ 16 | 17 | --- 18 | 19 | ## Wichtige Kommandos 20 | 21 | ```sh 22 | # Installation einer toolchain 23 | $ rustup install stable 24 | # Auswählen einer standard-toolchain 25 | $ rustup default stable 26 | # Anzeigen der Dokumentation im Browser 27 | $ rustup doc [--std] 28 | # Auflisten unterstützter targets 29 | $ rustup target list 30 | # Hinzufügen eines Targets zum installieren 31 | $ rustup target add 32 | # Auflisten/Hinzufügen einer Komponente 33 | $ rustup component list|add 34 | ``` 35 | 36 | --- 37 | 38 | # Erste Schritte 39 | 40 | Führen Sie folgende Kommandos aus: 41 | 42 | ```sh 43 | $ rustup component add rust-src 44 | $ rustup component add rust-docs 45 | $ rustup install nightly 46 | ``` 47 | 48 | Dies läd die Quelltexte der Standardbibliothek und 49 | die Dokumentation zur Komplettierung und Offlineverwendung runter. 50 | 51 | --- 52 | 53 | ## Inhalt einer Toolchain 54 | 55 | * rustc 56 | * cargo 57 | * rustdoc 58 | * rust-(lldb|gdb) 59 | * libcore/libstd 60 | 61 | Die genaue Art des Debuggers ist Platformabhängig. 62 | 63 | --- 64 | 65 | ## rustc 66 | 67 | ```sh 68 | $ rustc --help 69 | ``` 70 | 71 | Der Rust-Compiler übernimmt das kompilieren und linken von Rust-Code. 72 | 73 | `rustc` ist annähernd komplett in Rust geschrieben. 74 | 75 | --- 76 | 77 | ## Funktionstest 78 | 79 | ```rust 80 | fn main() { 81 | println!("Hello, World!"); 82 | } 83 | ``` 84 | 85 | --- 86 | 87 | ```sh 88 | $ rustc hello_world.rs 89 | $ ./hello_world 90 | Hello, World! 91 | ``` 92 | 93 | --- 94 | 95 | ## Cargo 96 | 97 | ```sh 98 | $ cargo --help 99 | ``` 100 | 101 | --- 102 | 103 | Cargo ist Rusts Build- und Codeverwaltungs-Toolchain. 104 | 105 | Cargo wird mit `rustc` ausgeliefert, ist aber nicht fest an einer `rustc`-Version gebunden. 106 | 107 | --- 108 | 109 | ## Nochmal mit cargo 110 | 111 | ```sh 112 | $ cargo new hello-world --bin 113 | $ cd hello-world 114 | $ cat hello-world 115 | fn main() { 116 | println!("Hello, world!"); 117 | } 118 | $ cargo build 119 | Compiling hello-world v0.1.0 (file:///Users/skade/Code/rust/scratchpad/hello-world) 120 | Finished debug [unoptimized + debuginfo] target(s) in 0.35 secs 121 | $ cargo run 122 | Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs 123 | Running `target/debug/hello-world` 124 | Hello, world! 125 | ``` 126 | 127 | --- 128 | 129 | ## Ein wenig umschauen 130 | 131 | * Was steht in Cargo.toml? 132 | * Was steht in Cargo.lock? 133 | 134 | --- 135 | 136 | ## Cargo verwaltet auch Tools 137 | 138 | ```sh 139 | $ cargo +nightly install clippy 140 | $ cargo +nightly install rustfmt 141 | ``` 142 | 143 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/intro.chapter: -------------------------------------------------------------------------------- 1 | # Rust in drei Tagen 2 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/iterators-again.chapter: -------------------------------------------------------------------------------- 1 | # Nochmal Iteratoren 2 | 3 | --- 4 | 5 | ## Generische Iteratoren zurückgeben 6 | 7 | Momentan erlaubt Rust keine generischen Typen als Rückgabewerte. Hier müssen Trait-Objekte verwendet werden. 8 | 9 | ```rust 10 | fn main() { 11 | let v = vec![1,2,3]; 12 | let i = make_iter(&v); 13 | } 14 | 15 | fn make_iter<'a>(v: &'a Vec) -> Box + 'a> { 16 | Box::new(v.iter()) 17 | } 18 | ``` 19 | 20 | Dieses Problem wird bald behoben. 21 | 22 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/libcore-and-libstd.chapter: -------------------------------------------------------------------------------- 1 | # libcore und libstd 2 | 3 | --- 4 | 5 | Rust wird mit 2 Grundbibliotheken, libcore und libstd ausgeliefert. 6 | 7 | --- 8 | 9 | libcore enthält alle Typen, die zum funktionieren der Sprache benötigt werden. 10 | 11 | libcore ist allokationsfrei. 12 | 13 | --- 14 | 15 | libcore wird meist nicht direkt verwendet, da ihr öffentliches Interface von libstd reexportiert wird. 16 | 17 | --- 18 | 19 | libstd liefert Standardfunktionen, zum Beispiel Interaktion mit dem Dateisystem. Sie hat darüber hinaus eine Abhängigkeit zu libc. 20 | 21 | 22 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/little-helpers.chapter: -------------------------------------------------------------------------------- 1 | # Kleine Hilfestellungen zum Start 2 | 3 | --- 4 | 5 | Strings in Rust sind ein Thema für sich. 6 | 7 | Daher werden sie später in einem eigenen Abschnitt behandelt. 8 | 9 | --- 10 | 11 | ## Strings ohne Nachdenken 12 | 13 | ```rust 14 | fn main() { 15 | let hello = String::from("Hello World"); 16 | println!("{}", hello); 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ## Code Style 23 | 24 | * 4 Spaces 25 | * Keine tabs 26 | * Blockklammern in eine eigene Zeile 27 | 28 | --- 29 | 30 | ## println!() 31 | 32 | ```rust 33 | fn main() { 34 | let hello = String::from("Hello World"); 35 | println("{}", hello); // string display 36 | println("{:?}", hello); // Debug 37 | } 38 | ``` 39 | 40 | --- 41 | 42 | ## Use the heap, Luke! 43 | 44 | Wir verwenden für die ersten Schritte: 45 | 46 | * String 47 | * `Vec` (Vektoren) 48 | * Plain `struct`s 49 | 50 | ```rust 51 | struct Point { 52 | x: i32, 53 | y: i32 54 | } 55 | 56 | fn main() { 57 | let hello = String::from("Hello World"); 58 | let vec = vec![1,2,3]; 59 | let point = Point { x: 1, y: 2}; 60 | } 61 | ``` 62 | 63 | --- 64 | 65 | ## \#[derive(Debug)] 66 | 67 | ```rust 68 | #[derive(Debug)] 69 | struct Point { 70 | x: i32, 71 | y: i32 72 | } 73 | 74 | fn main() { 75 | let point = Box::new(Point { x: 1, y: 2}); 76 | println!("{:?}", point); 77 | } 78 | ``` 79 | 80 | Funktioniert für alle Datenstrukturen. 81 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/macros.chapter: -------------------------------------------------------------------------------- 1 | # Macros 2 | 3 | --- 4 | 5 | Rust besitzt eine Macro-Sprache. Siehe [The Little Book Of Macros](http://doc.crates.io/manifest.html). 6 | 7 | --- 8 | 9 | ## Wichtige Macros 10 | 11 | * `try!(result)` Behandlung von Results 12 | * `println!(pattern, [werte])` Einfaches Schreiben auf stdout 13 | * `format!(patter, [werte])` wie `println!`, gibt aber Strings zurück 14 | * `write!(buf, string)` Einfaches Schreiben von Strings in Buffer 15 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/match.chapter: -------------------------------------------------------------------------------- 1 | # Control-Flow mit `match` 2 | 3 | --- 4 | 5 | Um die Varianten von Enums zu prüfen, wird `match` verwendet. 6 | 7 | --- 8 | 9 | ```rust 10 | fn main() { 11 | let mut args = std::env::args(); 12 | 13 | match args.nth(1) { 14 | Some(arg) => { println!("Argument übergeben: {}", arg)}, 15 | None => { println!("Kein Argument übergeben") } 16 | } 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ## Alternative: if-let 23 | 24 | ```rust 25 | fn main() { 26 | let mut args = std::env::args(); 27 | 28 | if let Some(arg) = args.nth(1) { 29 | println!("Argument übergeben: {}", arg); 30 | } 31 | } 32 | ``` 33 | 34 | --- 35 | 36 | ```rust 37 | fn main() { 38 | let maybe_file = std::fs::File::open("Gibt's nicht!"); 39 | 40 | match maybe_file { 41 | Ok(f) => { println!("Datei geöffnet! Debug: {:?}", f) }, 42 | Err(e) => { println!("Datei nicht geöffnet! Fehler: {:?}", e) } 43 | } 44 | } 45 | ``` 46 | 47 | --- 48 | 49 | Matches müssen alle Varianten abdecken. 50 | 51 | --- 52 | 53 | ## Ignorieren weiterer Varianten 54 | 55 | ```rust 56 | fn main() { 57 | let maybe_file = std::fs::File::open("Gibt's nicht!"); 58 | 59 | match maybe_file { 60 | Err(e) => { println!("Datei nicht geöffnet! Fehler: {:?}", e) } 61 | _ => {} 62 | } 63 | } 64 | ``` 65 | 66 | --- 67 | 68 | Results tragen eine besondere Markierung: sie dürfen nicht ignoriert werden! 69 | 70 | ```rust 71 | fn main() { 72 | let maybe_file = std::fs::File::open("Gibt's nicht!"); 73 | } 74 | ``` 75 | 76 | Lösung: matchen oder weiterreichen. 77 | 78 | --- 79 | 80 | `match` funktioniert nicht nur auf enums: 81 | 82 | ```rust 83 | fn main() { 84 | let number = 4; 85 | 86 | match number { 87 | 0 => println!("Number is 0"), 88 | _ => println!("Number is something else") 89 | } 90 | } 91 | ``` 92 | 93 | --- 94 | 95 | `match` und `if` Ausdrücke: 96 | 97 | ```rust 98 | fn main() { 99 | let mut args = std::env::args(); 100 | 101 | let value = if let Some(arg) = args.at(1) { 102 | arg 103 | } else { 104 | "default!".to_string() 105 | }; 106 | } 107 | ``` -------------------------------------------------------------------------------- /presentation/chapters/de-DE/mutability.chapter: -------------------------------------------------------------------------------- 1 | # Mutabilität 2 | 3 | --- 4 | 5 | Moderne Programmiersprachen unterscheiden sich meist in ihrer Haltung zur Mutabilität von Daten. 6 | 7 | Wo landet Rust? 8 | 9 | --- 10 | 11 | ## Ein Beispiel 12 | 13 | ```rust 14 | fn main() { 15 | let answer = 42; 16 | answer = 32; 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ## Richtig 23 | 24 | ```rust 25 | fn main() { 26 | let mut answer = 42; 27 | answer = 32; 28 | } 29 | ``` 30 | 31 | --- 32 | 33 | Rust verlangt, mutable Daten zu deklarieren. 34 | 35 | Mutabilität ist immer direkt aus dem Code ersichtlich. 36 | 37 | --- 38 | 39 | Mutabilität ist fundamental wichtig für Rust und wird uns regelmässig wieder begegnen. 40 | 41 | --- 42 | 43 | Mutabilität ist eine Eigenschaft von Variablen und Bindungen, nicht der daran gebunden Daten. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/send-and-sync.chapter: -------------------------------------------------------------------------------- 1 | # Send & Sync 2 | 3 | --- 4 | 5 | Rusts Unterstützung für Nebenläufigkeit basiert auf 2 Traits: 6 | 7 | * `Send` markiert eine Struktur als sicher zum *senden* zwischen Threads. 8 | * `Sync` kennzeichnet eine Struktur als sicher zum *teilen* zwischen Threads sicher ist. 9 | + (`&T` ist `Send`, wenn `T` `Sync`) 10 | 11 | Beide sind sogenannte "Marker". 12 | 13 | --- 14 | 15 | Rust nutzt diese Traits, um Datenrennen zu verhindern. 16 | 17 | Sie sind - wenn möglich - *automatisch abgeleitet*. 18 | 19 | --- 20 | 21 | ## Automatisch abgeleitet 22 | 23 | ```rust 24 | use std::thread; 25 | 26 | #[derive(Debug)] 27 | struct Thing; 28 | 29 | // Can send between threads! 30 | fn main() { 31 | let thing = Thing; 32 | 33 | thread::spawn(move || { 34 | println!("{:?}", thing); 35 | }).join(); 36 | } 37 | ``` 38 | 39 | --- 40 | 41 | Es gibt einige wichtige Typen, die nicht `Send` oder `Sync` sind. 42 | 43 | Beispiele sind `Rc`, rohe Zeiger und `UnsafeCell`. 44 | 45 | --- 46 | 47 | ## Beispiel: `Rc` 48 | 49 | ```rust 50 | use std::rc::Rc; 51 | use std::thread; 52 | 53 | // Does not work! 54 | fn main() { 55 | let only_one_thread = Rc::new(true); 56 | 57 | thread::spawn(move || { 58 | println!("{:?}", only_one_thread); 59 | }).join(); 60 | } 61 | ``` 62 | 63 | --- 64 | 65 | ## Beispiel: `Rc` 66 | 67 | ``` 68 | error[E0277]: the trait bound `std::rc::Rc: std::marker::Send` is not satisfied 69 | --> :7:5 70 | | 71 | 7 | thread::spawn(move || { 72 | | ^^^^^^^^^^^^^ the trait `std::marker::Send` is not implemented for `std::rc::Rc` 73 | ``` 74 | 75 | --- 76 | 77 | ## Implementierung 78 | 79 | Es ist möglich, die Implementierung von `Send` und `Sync` einem Typ hinzuzufügen. 80 | 81 | ```rust 82 | struct Thing(*mut String); 83 | 84 | unsafe impl Send for Thing {} 85 | unsafe impl Sync for Thing {} 86 | ``` 87 | 88 | In diesen Fällen ist die Aufgabe der Implementierung, die Sicherheitsgarantien herzustellen. 89 | 90 | --- 91 | 92 | ## Beziehungen 93 | 94 | Wenn ein Typ sowohl `Sync` als auch `Copy` implementiert, kann er `Send` auch implementieren. 95 | 96 | --- 97 | 98 | ## Beziehungen 99 | 100 | Ein Typ `&T` kann `Send` implementieren, wenn der Typ `T` auch `Sync` implementiert. 101 | 102 | ```rust 103 | unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} 104 | ``` 105 | 106 | --- 107 | 108 | ## Beziehungen 109 | 110 | Ein Typ `&mut T` kann `Send` implementieren, wenn der Typ `T` auch `Send` implementiert. 111 | 112 | ```rust 113 | unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} 114 | ``` 115 | 116 | --- 117 | 118 | ## Konsequenzen 119 | 120 | Was sind die Konsequenzen von `Send` und `Sync`? 121 | 122 | --- 123 | 124 | ## Konsequenzen 125 | 126 | Das Tragen dieser Informationen auf der Typ-System-Ebene ermöglicht das erkennen von Nebenläufigkeits Problemen zur * Übersetzungszeit *. 127 | 128 | Dies verhindert, dass diese Fehlerklasse die Produktionssysteme erreicht. 129 | 130 | `Send` und `Sync` sind unabhängig von der Art der Nebenläufigkeit (async, threaded, etc.). -------------------------------------------------------------------------------- /presentation/chapters/de-DE/smart-pointers.chapter: -------------------------------------------------------------------------------- 1 | # Spezielle Pointer in Rust 2 | 3 | --- 4 | 5 | Rust bietet mehrere spezielle Pointer-Typen an, um verschiedene Szenarien zu handhaben. 6 | 7 | Generell ist ihnen gemein: sie werden über Ownership gemanagt. 8 | 9 | --- 10 | 11 | ## `std::rc::Rc` 12 | 13 | Laufzeit-Reference-Counter innerhalb eines Threads. 14 | 15 | ```rust 16 | use std::rc::Rc; 17 | 18 | struct Point { 19 | x: i32, 20 | y: i32, 21 | } 22 | 23 | fn main() { 24 | let rced_point = Rc::new(Point { x: 1, y: 1}); 25 | let first_handle = rced_point.clone(); 26 | let second_handle = rced_point.clone(); 27 | } 28 | ``` 29 | 30 | --- 31 | 32 | ## Semantik 33 | 34 | * `Rc` ist ein Handle auf die enthaltenen Daten 35 | * Das Handle kann geklont werden 36 | * Wenn das letzte Handle droppt, droppen die Daten mit 37 | * `Rc` implementiert `Deref` 38 | 39 | --- 40 | 41 | ## `std::rc::Weak` 42 | 43 | Schwacher Pointer auf Daten. 44 | 45 | ```rust 46 | use std::rc::Rc; 47 | 48 | struct Point { 49 | x: i32, 50 | y: i32, 51 | } 52 | 53 | fn main() { 54 | let rced_point = Rc::new(Point { x: 1, y: 1}); 55 | let first_handle = rced_point.clone(); 56 | let weak = Rc::downgrade(first_handle); 57 | } 58 | ``` 59 | 60 | --- 61 | 62 | ## Semantik 63 | 64 | * Ähnlich `Rc`, die Existenz der Daten ist aber nicht garantiert 65 | * Single-Threaded: Die Daten sind garantiert über die Zeit einer Operation verfügbar 66 | * Wird _nicht_ automatisch dereferenziert 67 | * `Rc`-Kreise sind Speicherlecks, Weak-Pointer verhindern das 68 | 69 | --- 70 | 71 | ## Nutzen 72 | 73 | * Häufig in Datenstrukturen gebraucht, die komplexe Querreferenzierungen brauchen 74 | * Höhere Laufzeitkosten für mehr Flexibilität 75 | 76 | --- 77 | 78 | ## `std::sync::Arc` 79 | 80 | Ein teurer `Rc`, der über Threadgrenzen hinweg funktioniert, da ein atomarer Zähler 81 | zum Inkrementieren verwendet wird. 82 | 83 | --- 84 | 85 | ## Anmerkung 86 | 87 | Nutzen Sie `Arc` nicht "auf Verdacht" - `rustc` lehnt Code ab, der `Rc` über Threadgrenzen verwendet. 88 | 89 | --- 90 | 91 | ## `std::borrow::Cow` 92 | 93 | * Copy-on-write 94 | * Abstrahiert über Leihe und Besitz 95 | * Klont enthaltene Daten nur bei Notwendigkeit 96 | * https://doc.rust-lang.org/std/borrow/enum.Cow.html#examples 97 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/stack-and-heap.chapter: -------------------------------------------------------------------------------- 1 | # Stack und Heap 2 | 3 | --- 4 | 5 | Rust allokiert standardmässig auf dem Stack. 6 | 7 | --- 8 | 9 | ## Stack-Allokation 10 | 11 | ```rust 12 | struct Point { 13 | x: i32, 14 | y: i32 15 | } 16 | 17 | fn main() { 18 | let point = Point { x: 1, y: 1}; 19 | } 20 | ``` 21 | 22 | --- 23 | 24 | ## Box 25 | 26 | Heap-Allokation wird in Rust durch den Typ `Box` dargestellt. 27 | 28 | ```rust 29 | struct Point { 30 | x: i32, 31 | y: i32 32 | } 33 | 34 | fn main() { 35 | let point = Point { x: 1, y: 1}; 36 | let point_on_heap = Box::new(point); 37 | } 38 | ``` 39 | 40 | --- 41 | 42 | ## Ownership und Borrowing 43 | 44 | `Box` wird besessen, die Daten können allerdings ausgeliehen werden. 45 | 46 | ```rust 47 | #[derive(Debug)] 48 | struct Point { 49 | x: i32, 50 | y: i32 51 | } 52 | 53 | fn main() { 54 | let point = Point { x: 1, y: 1}; 55 | let point_on_heap = Box::new(point); 56 | print_point(&point_on_heap); 57 | } 58 | 59 | fn print_point(p: &Point) { 60 | println!("{:?}", p); 61 | } 62 | ``` 63 | 64 | --- 65 | 66 | ## Placement in 67 | 68 | Momentan ist es _nicht_ möglich, Daten direkt an einer gewünschten Stelle zu allokieren. Das nötige Feature nennt sich "Placement in". 69 | 70 | [Details zum Stand hier](https://internals.rust-lang.org/t/lang-team-minutes-feature-status-report-placement-in-and-box/4646) 71 | 72 | --- 73 | 74 | In den meisten Fällen optimiert LLVM dies aber eh schon raus. 75 | 76 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/std-lib-tour.chapter: -------------------------------------------------------------------------------- 1 | ## TODO std::ops, std::collections, mpsc, etc. -------------------------------------------------------------------------------- /presentation/chapters/de-DE/unsafe.chapter: -------------------------------------------------------------------------------- 1 | ## Unsicheres Rust 2 | 3 | Rusts Typsystem bietet viele Garantien, diese machen manchmal jedoch Lösungen schwerer und unmöglich. 4 | 5 | Daher hat Rust das Konzept von `unsicherem Code`. 6 | 7 | --- 8 | 9 | Unsicherer Code darf: 10 | * Beliebige Speicherzugriffe durchführen 11 | * Rohe Pointer dereferenzieren 12 | * Externe Funktionen aufrufen 13 | * Eigenschaften wie `Send` und `Sync` feststellen 14 | * Globale (unsynchronisierte) Variablen schreiben 15 | 16 | --- 17 | 18 | Nicht unsicher sind: 19 | * Konvertierungen in rohe Pointer 20 | * Speicherlecks 21 | 22 | --- 23 | 24 | Unsicherer Code sollte niemals: 25 | * Genutzt werden um Speicher zu managen, der von einem anderen Allokator gemanagt wird. 26 | - Konstruieren Sie niemals einen `std::vec::Vec` aus einem C++-Vektor und lassen ihn dann fallen. 27 | * borrowck umgehen, z.B. Lebenszeiten oder Mutabilität eines Typens umändern 28 | - Beliebte Quelle von "aber ich war mir so sicher, dass das geht" 29 | 30 | --- 31 | 32 | ## Rusts kleines Geheimnis 33 | 34 | Beim implementieren von Datenstrukturen ist unsafe recht häufig. 35 | 36 | Sicheres Rust ist die schlechteste Sprache zum implementieren von Linked Lists. Es gibt eine [ganze Abhandlung darüber](TODO: Link) 37 | 38 | --- 39 | 40 | Unsicherer Code benötigt _immer_ eine Markierung durch `unsafe`. 41 | 42 | ```rust 43 | fn main() { 44 | let pointer_to_int = &mut i32; 45 | let raw = pointer_to_int as *mut i32; 46 | unsafe { deref_pointer(raw) }; 47 | } 48 | 49 | unsafe deref_pointer(p: *mut T) { 50 | unsafe { println("{:?}", *p } 51 | } 52 | ``` 53 | 54 | --- 55 | 56 | ## Fallen von `unsafe` 57 | 58 | * Nicht jedes Beispiel ist so simpel. `unsafe` _muss_ die Invarianten von Rust einhalten! 59 | * Dies gilt vor allem für Ownership und mutables Borrowing 60 | - `unsafe` kann dazu führen, dass ein Wert 2 Owner hat -> double free 61 | - `unsafe` kann dazu führen, dass eigentlich immutable Daten temporär mutabel sind, was zu vielen Problem führen kann 62 | 63 | --- 64 | 65 | Rust erlaubt einem, sich in den Fuss zu schiessen, es möchte nur vorher, dass man die Waffe aus dem Holster nimmt und die Sicherung entriegelt. 66 | 67 | --- 68 | 69 | ## Praktisches Beispiel 70 | 71 | Da Rust aliasing verbietet, kann man in sicherem Rust keine Slice in 2 Slices teilen. 72 | 73 | ```rust 74 | #[inline] 75 | fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { 76 | let len = self.len(); 77 | let ptr = self.as_mut_ptr(); 78 | 79 | unsafe { 80 | assert!(mid <= len); 81 | 82 | (from_raw_parts_mut(ptr, mid), 83 | from_raw_parts_mut(ptr.offset(mid as isize), len - mid)) 84 | } 85 | } 86 | ``` -------------------------------------------------------------------------------- /presentation/chapters/de-DE/usage-examples.chapter: -------------------------------------------------------------------------------- 1 | # Usage examples 2 | 3 | --- 4 | 5 | ## Beispiel 6 | 7 |
8 | 9 | --- 10 | 11 | ## SVG 12 | 13 |
14 | +------+ top
15 | |      |
16 | |      |
17 | +------+ bottom
18 | 
19 | -------------------------------------------------------------------------------- /presentation/chapters/de-DE/working-with-nightly.chapter: -------------------------------------------------------------------------------- 1 | # Arbeiten mit nightly 2 | 3 | --- 4 | 5 | ## Warum? 6 | 7 | * Abhängigkeiten können nightly verlangen 8 | * Kompilierzeiten und Fehlermeldungen sind manchmal besser (manchmal nicht) 9 | * Es gibt mehrere Funktionen, die noch nicht stabil sind 10 | * Der stabile Compiler erlaubt strikt keinen Zugriff auf unfertige Features 11 | * Compiler-Plugins 12 | 13 | 14 | --- 15 | 16 | ## Kürzliche Änderungen 17 | 18 | In [Rust 1.15](https://blog.rust-lang.org/2017/02/02/Rust-1.15.html) wurde die Funktion 'custom derive' stabilisiert. 19 | 20 | Dies war für viele Projekte der einzige Grund, nightly zu verwenden. 21 | 22 | Es wird erwartet, daß die Anzahl von Paketen, die nightly erfordern, signifikant abnehmen wird. 23 | 24 | --- 25 | 26 | ## Entwickeln auf nightly 27 | 28 | `rustup` kann verwendet werden, um die Version in einem bestimmten Verzeichnis verwendet außer Kraft zu setzen. 29 | 30 | ```bash 31 | cd /nightly_project 32 | rustup override set nightly 33 | ``` 34 | 35 | --- 36 | 37 | ## Funktionen 38 | 39 | Die Features werden hinter "Feature Flags" versteckt, die projektweit aktiviert sind. 40 | 41 | Einige Beispiele: 42 | 43 | * `asm`, die Inline assembly unterstützt 44 | * `no_std`, deaktiviert implizite `extern crate std` 45 | * `inclusive_range`, ähnlich dem stabilen `exclusive_range` 46 | * `conversative_impl_trait`, aktiviert die `impl Trait`-Rückgabesyntax 47 | 48 | --- 49 | 50 | ## Aktivieren von Funktionen 51 | 52 | Um eine Funktion zu aktivieren, fügen Sie die folgende Zeile in `src/main.rs` (für ausführbare Dateien) oder `src/lib.rs` (für Bibliotheken) ein: 53 | 54 | ```rust 55 | #![feature(asm, no_std)] 56 | ``` 57 | 58 | --- 59 | 60 | ## Compiler-Plugins 61 | 62 | Compiler-Plugins ergänzen Rust um zusätzliche Funktionen. Beispielsweise: 63 | 64 | * (Früher) Eigene Derive-Funktionen 65 | * Linter, wie `clippy` 66 | * Bibliotheken wie [`regex_macros`](https://github.com/rust-lang/regex#usage-regex-compiler-plugin), die Syntax-Erweiterungen darstellen 67 | 68 | --- 69 | 70 | ## Aktivieren von Compiler-Plugins 71 | 72 | Um ein Compiler-Plugin zu aktivieren, fügen Sie folgende Zeile in `src/main.rs` (für ausführbare Dateien) oder` src/lib.rs` (für Bibliotheken) ein: 73 | 74 | ```rust 75 | #![plugin(some_plugin)] 76 | ``` 77 | 78 | --- 79 | 80 | ## Warnung 81 | 82 | Es ist unbekannt, wann Compiler-Plugins stabilisiert werden. 83 | 84 | --- 85 | 86 | ## Stabile Entwicklung auf nightly 87 | 88 | Es empfiehlt sich, den nightly compiler zu verwenden, der einer Release-Version entspricht. -------------------------------------------------------------------------------- /presentation/chapters/en-US/advanced-generics-bounds.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/advanced-generics-bounds.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/borrowing.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/borrowing.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/closures.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/closures.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/conversion-patterns.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/conversion-patterns.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/crates.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/crates.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/data-structures.chapter: -------------------------------------------------------------------------------- 1 | # Data Structures 2 | 3 | --- 4 | 5 | ## Structs 6 | 7 | --- 8 | 9 | ## Definition 10 | 11 | ```rust 12 | struct Point { 13 | x: i32, 14 | y: i32, 15 | } 16 | ``` 17 | 18 | --- 19 | 20 | ## Allocation 21 | 22 | ```rust 23 | struct Point { 24 | x: i32, 25 | y: i32, 26 | } 27 | 28 | fn main() { 29 | let p = Point { x: 1, y: 1 }; 30 | } 31 | ``` 32 | 33 | --- 34 | 35 | ## Field Access 36 | 37 | ```rust 38 | struct Point { 39 | x: i32, 40 | y: i32, 41 | } 42 | 43 | fn main() { 44 | let p = Point { x: 1, y: 2 }; 45 | println!("{}", p.x); 46 | println!("{}", p.y); 47 | } 48 | ``` 49 | 50 | --- 51 | 52 | ## Tuples 53 | 54 | ```rust 55 | fn main() { 56 | let p = (1, 2); 57 | println!("{}", p.0); 58 | println!("{}", p.1); 59 | } 60 | ``` 61 | 62 | --- 63 | 64 | ## Tuple Structs 65 | 66 | ```rust 67 | struct Point(i32,i32); 68 | 69 | fn main() { 70 | let p = Point(1, 2); 71 | println!("{}", p.0); 72 | println!("{}", p.1); 73 | } 74 | ``` 75 | 76 | --- 77 | 78 | ## Enums 79 | 80 | ```rust 81 | enum Direction { 82 | Right, 83 | Left, 84 | Up, 85 | Down, 86 | } 87 | 88 | fn main() { 89 | let direction = Direction::Left; 90 | } 91 | ``` 92 | 93 | The different choices of Enums are called "variants." 94 | 95 | --- 96 | 97 | ## Enums with Values 98 | 99 | ```rust 100 | enum Movement { 101 | Right(i32), 102 | Left(i32), 103 | Up(i32), 104 | Down(i32), 105 | } 106 | 107 | fn main() { 108 | let movement = Movement::Left(12); 109 | } 110 | ``` 111 | 112 | --- 113 | 114 | ## Enums with Structured Variants 115 | 116 | ```rust 117 | enum Actions { 118 | StickAround, 119 | MoveTo { x: i32, y: 32}, 120 | } 121 | 122 | fn main() { 123 | let action = Actions::MoveTo { x: 0, y: 0 }; 124 | } 125 | ``` 126 | 127 | --- 128 | 129 | ## `null` 130 | 131 | Does not exist. 132 | 133 | --- 134 | 135 | ## Are There Variant Types? 136 | 137 | No, not at the moment! 138 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/deref-coersions.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/deref-coersions.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/documentation.chapter: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | --- 4 | 5 | ## `rustdoc` 6 | 7 | Rust provides a standard documentation tool called `rustdoc`. It is commonly used through `cargo doc`. 8 | 9 | Because of this Rust code is almost always documented in a common format. 10 | 11 | --- 12 | 13 | ## `std` Documentation 14 | 15 | The standard library documentation is hosted at https://doc.rust-lang.org/std/. 16 | 17 | A local, offline version can be opened with: 18 | 19 | ```bash 20 | rustup doc --std 21 | ``` 22 | 23 | --- 24 | 25 | ## Crate Documentation 26 | 27 | Documentation for crates hosted on http://crates.io/ can be found at https://docs.rs/. 28 | 29 | Some crates may also have other documentation found via the "Documentation" link on their listing in http://crates.io/. 30 | 31 | --- 32 | 33 | ## Example: A Module 34 | 35 | 36 | 37 | --- 38 | 39 | ## Example: A Module 40 | 41 | This page documents the `vec` module. 42 | 43 | It starts with some examples, then lists any `struct`s, traits, or functions the module exports. 44 | 45 | --- 46 | 47 | ## How is it Generated? 48 | 49 | `rustdoc` can read Rust code and Markdown documents. 50 | 51 | `//!` and `///` comments are read as Markdown. 52 | 53 | ```rust 54 | //! Module documentation comment like the 'examples' section from `std::vec`. 55 | 56 | /// Documents functions, `struct`s, and traits. 57 | /// Here it documents a function. 58 | fn function_with_documentation() {} 59 | 60 | // This comment will not appear as documentation. 61 | // The function still shows. 62 | fn function_without_documentation() {} 63 | ``` 64 | 65 | --- 66 | 67 | ## Example: Components 68 | 69 | 70 | 71 | --- 72 | 73 | ## Example: Functions 74 | 75 | 76 | 77 | --- 78 | 79 | ## Code Examples 80 | 81 | By default code blocks in documentation are tested. 82 | 83 |

84 | /// ```rust
85 | /// assert_eq!(always_true(), true)
86 | /// ```
87 | fn always_true() -> bool { true }
88 | 
89 | 90 | --- 91 | 92 | ## Navigation 93 | 94 | The arguments and return types of functions are links to their respective types. 95 | 96 | The sidebar on the left offers quick navigate to other parts of the module. 97 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/error-handling.chapter: -------------------------------------------------------------------------------- 1 | # Error Handling 2 | 3 | --- 4 | 5 | Error handling is explicit in Rust. 6 | 7 | Any function with known error conditions returns a `Result`. 8 | 9 | **There are no exceptions.** 10 | 11 | --- 12 | 13 | ```rust 14 | fn this_can_fail(succeeds: bool) -> Result { 15 | if succeeds { 16 | Ok(String::from("It worked!")) 17 | } else { 18 | Err(String::from("It didn't work!")) 19 | } 20 | } 21 | 22 | fn main() { 23 | let outcome = this_can_fail(true); 24 | } 25 | ``` 26 | 27 | --- 28 | 29 | ## Results Must Be Used 30 | 31 | ``` 32 | warning: unused variable: `outcome`, #[warn(unused_variables)] on by default 33 | --> :10:9 34 | | 35 | 10 | let outcome = this_can_fail(true); 36 | | ^^^^^^^ 37 | ``` 38 | 39 | --- 40 | 41 | ## Using Results With `match` 42 | 43 | ```rust 44 | fn main() { 45 | match this_can_fail(false) { 46 | Ok(val) => println!("Worked: {}", val), 47 | Err(err) => println!("Failed: {}", err), 48 | } 49 | } 50 | ``` 51 | 52 | --- 53 | 54 | ## Using Results With Conditionals 55 | 56 | Check for success with `is_ok()`, errors with `is_err()`: 57 | 58 | ```rust 59 | fn main() { 60 | if this_can_fail(false).is_ok() { 61 | println!("It worked!"); 62 | } else { 63 | println!("It didn't work!") 64 | } 65 | } 66 | ``` 67 | 68 | --- 69 | 70 | ## Using Results With `?` 71 | 72 | Use `?` in functions with multiple possible failures. 73 | 74 | ```rust 75 | fn multiple_possible_failures() -> Result { 76 | this_can_fail(true)?; 77 | println!("After first potential failure"); 78 | this_can_fail(false)?; 79 | println!("After second potential failure"); 80 | Ok(String::from("All done")) 81 | } 82 | 83 | fn main() { 84 | multiple_possible_failures(); 85 | } 86 | ``` 87 | 88 | --- 89 | 90 | ## Using Results With `?` 91 | 92 | Output: 93 | 94 | ``` 95 | After first potential failure 96 | ``` 97 | 98 | Note the early exit. 99 | 100 | --- 101 | 102 | ## Results Are Wrapper Types 103 | 104 | It's possible to change a `Result` into a `Result` without unwrapping it. 105 | 106 | Transforming a `Result` into a `Result` is also possible. 107 | 108 |
109 | +-----+   +-----+   +-----+
110 | | T,E |-->| U,E |-->| U,X |
111 | +-----+   +-----+   +-----+
112 | 
113 | 114 | --- 115 | 116 | ## Mapping Result Values 117 | 118 | ```rust 119 | fn main() { 120 | let some_result = this_can_fail(true); 121 | // This is only run if `some_result` is an `Ok` variant. 122 | let mapped_result = some_result.map(|val| val.len()); 123 | println!("{:?}", mapped_result); 124 | } 125 | ``` 126 | 127 | `map_err()` is also available. -------------------------------------------------------------------------------- /presentation/chapters/en-US/functions.chapter: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | --- 4 | 5 | ## Declaration 6 | 7 | ```rust 8 | fn add(first: i32, second: i32) -> i32 { 9 | first + second 10 | } 11 | ``` 12 | 13 | --- 14 | 15 | ## Arguments 16 | 17 | ```rust 18 | fn by_value(arg: i32) {} 19 | 20 | fn by_reference(arg: &i32) {} 21 | 22 | fn by_mutable_reference(arg: &mut i32) {} 23 | ``` 24 | 25 | --- 26 | 27 | ## Returning 28 | 29 | Returning is optional. Signatures must be complete. 30 | 31 | ```rust 32 | fn return_nothing() {} 33 | 34 | fn return_a_random() -> i32 { 35 | 4 // Guaranteed random, chosen by dice roll 36 | } 37 | 38 | fn maybe_return_a_random(should: bool) -> Option { 39 | if should { Some(4) } else { None } 40 | } 41 | ``` 42 | 43 | --- 44 | 45 | ## Generic Functions 46 | 47 | Generic functions have type parameters. 48 | 49 | ```rust 50 | fn accept_any_type(arg: T) { 51 | // ... 52 | } 53 | 54 | fn transmute(arg: T) -> U { 55 | // ... 56 | } 57 | ``` 58 | 59 | --- 60 | 61 | ## With Bounds 62 | 63 | Generic functions can also have bounds. 64 | 65 | These are equivalent: 66 | 67 | ```rust 68 | fn with_bound(arg: T) -> String { 69 | // ... 70 | } 71 | 72 | fn where_clause(arg: T) -> String where T: Display { 73 | // ... 74 | } 75 | ``` 76 | 77 | --- 78 | 79 | # Remarks 80 | 81 | * Types which do not have the `Copy` trait are consumed when passed by value. 82 | * Returning references may involve clarifying lifetimes (discussed later.) 83 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/generics-basics.chapter: -------------------------------------------------------------------------------- 1 | # Simple Generics 2 | 3 | --- 4 | 5 | Generics are fundamental for Rust. 6 | 7 | --- 8 | 9 | ## Generic Structs 10 | 11 | ```rust 12 | struct Point { 13 | x: Precision, 14 | y: Precision 15 | } 16 | 17 | fn main() { 18 | let point = Point { x: 1u32, y: 2 }; 19 | let point: Point { x: 1, y: 2 }; 20 | } 21 | ``` 22 | 23 | --- 24 | 25 | ## Type Inference 26 | 27 | Rust finds the types of all variables and generics with sufficient information. 28 | 29 | This only applies _inside_ of function limits. 30 | 31 | Signatures must always be fully entered. 32 | 33 | --- 34 | 35 | ## Generic Enums 36 | 37 | ```rust 38 | enum Either { 39 | Left(T), 40 | Right(X) 41 | } 42 | 43 | fn main() { 44 | let alternative: Either = Either::Left(i32); 45 | } 46 | ``` 47 | 48 | --- 49 | 50 | ## Important Generic Enums 51 | 52 | --- 53 | 54 | ## Option 55 | 56 | ```rust 57 | enum Option { 58 | Some(T), 59 | None 60 | } 61 | 62 | fn main() { 63 | let args = std::os::args; 64 | println!("{:?} {:?}", args.at(0), args.at(1)) 65 | } 66 | ``` 67 | 68 | Describes a value which does not have to be present. 69 | 70 | `None` is a value, and should not be confused with `null`. 71 | 72 | --- 73 | 74 | ## Result 75 | 76 | ```rust 77 | enum Result { 78 | Ok(T), 79 | Err(E) 80 | } 81 | 82 | fn main() { 83 | let file = std::fs::File::open("I don't exist!"); 84 | println!("{:?}", file); 85 | } 86 | ``` 87 | 88 | Describes whether an operation was successful and returns either the value or an error. 89 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/imports-modules-and-visibility.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/imports-modules-and-visibility.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/installation.chapter: -------------------------------------------------------------------------------- 1 | # The Toolchain 2 | 3 | Florian Gilcher 4 | 5 | --- 6 | 7 | https://www.rust-lang.org/en-US/install.html 8 | 9 | --- 10 | 11 | ## Rustup 12 | 13 | Rustup is the standard tool for managing Rusts compiler toolchain. 14 | 15 | http://rustup.rs/ 16 | 17 | --- 18 | 19 | ## Important Commands 20 | 21 | ```sh 22 | # Install a toolchain 23 | $ rustup install stable 24 | # Select a standard toolchain 25 | $ rustup default stable 26 | # View the documentation in the browser 27 | $ rustup doc [--std] 28 | # List supported targets 29 | $ rustup target list 30 | # Add a target to install 31 | $ rustup target add 32 | # List/Add a component 33 | $ rustup component list|add 34 | ``` 35 | 36 | --- 37 | 38 | # First Steps 39 | 40 | Execute the following commands: 41 | 42 | ```sh 43 | $ rustup component add rust-src 44 | $ rustup component add rust-docs 45 | ``` 46 | 47 | This loads the sources of the default library and documentation 48 | for completion and offline use. 49 | 50 | --- 51 | 52 | ## Content of the Toolchain 53 | 54 | * rustc 55 | * cargo 56 | * rustdoc 57 | * rust-(lldb|gdb) 58 | * libcore/libstd 59 | 60 | The debugger installed is platform dependent. 61 | 62 | --- 63 | 64 | ## rustc 65 | 66 | ```sh 67 | $ rustc --help 68 | ``` 69 | 70 | The Rust compiler builds and links Rust code. 71 | 72 | `rustc` is almost completely written in Rust. 73 | 74 | --- 75 | 76 | ## Functional Test 77 | 78 | ```rust 79 | fn main() { 80 | println!("Hello, World!"); 81 | } 82 | ``` 83 | 84 | --- 85 | 86 | ```sh 87 | $ rustc hello_world.rs 88 | $ ./hello_world 89 | Hello, World! 90 | ``` 91 | 92 | --- 93 | 94 | ## Cargo 95 | 96 | ```sh 97 | $ cargo --help 98 | ``` 99 | 100 | --- 101 | 102 | Cargo is Rusts build and package management tool. 103 | 104 | Cargo is installed along with `rustc`, but is not tightly bound to a `rustc` verison. 105 | 106 | --- 107 | 108 | ## Once more with Cargo 109 | 110 | ```sh 111 | $ cargo new hello-world --bin 112 | $ cd hello-world 113 | $ cat hello-world 114 | fn main() { 115 | println!("Hello, world!"); 116 | } 117 | $ cargo build 118 | Compiling hello-world v0.1.0 (file:///Users/skade/Code/rust/scratchpad/hello-world) 119 | Finished debug [unoptimized + debuginfo] target(s) in 0.35 secs 120 | $ cargo run 121 | Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs 122 | Running `target/debug/hello-world` 123 | Hello, world! 124 | ``` 125 | 126 | --- 127 | 128 | ## A Little Look Around 129 | 130 | * What is in Cargo.toml? 131 | * What is in Cargo.lock? 132 | 133 | --- 134 | 135 | ## Cargo Also Manages Tools 136 | 137 | ```sh 138 | $ cargo +nightly install clippy 139 | $ cargo +nightly install rustfmt 140 | ``` 141 | 142 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/intro.chapter: -------------------------------------------------------------------------------- 1 | # Rust Course 2 | 3 | Florian Gilcher 4 | 5 | --- 6 | 7 | ## Short Introduction 8 | 9 | * Rust is a new programming language from Mozilla Research. 10 | 11 | --- 12 | 13 | ## Focus 14 | 15 | * Safety 16 | * Speed 17 | * Concurrency 18 | 19 | --- 20 | 21 | ## All Rights Reserved 22 | 23 | --- 24 | 25 | ## Content 26 | 27 | * [Intro](index.html) 28 | * [Installation](index.html?chapter=installation&locale=en-US#) 29 | 30 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/lifetimes.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/lifetimes.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/little-helpers.chapter: -------------------------------------------------------------------------------- 1 | # A Bit of Help Getting Started 2 | 3 | --- 4 | 5 | Strings in Rust are a topic on their own. 6 | 7 | Therefore they will be covered fully in a seperate section later. 8 | 9 | --- 10 | 11 | ## Strings Without Thinking 12 | 13 | ```rust 14 | fn main() { 15 | let hello = String::from("Hello World"); 16 | println!("{}", hello); 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ## Code Style 23 | 24 | * 4 Spaces 25 | * No tabs 26 | * Block breaks on a seperate line. 27 | 28 | --- 29 | 30 | ## println!() 31 | 32 | ```rust 33 | fn main() { 34 | let hello = String::from("Hello World"); 35 | println("{}", hello); // string display 36 | println("{:?}", hello); // Debug 37 | } 38 | ``` 39 | 40 | --- 41 | 42 | ## Use the heap, Luke! 43 | 44 | We will use for the first steps: 45 | 46 | * `String` 47 | * `Vec` (Vectors) 48 | * Plain `struct`s 49 | 50 | ```rust 51 | struct Point { 52 | x: i32, 53 | y: i32 54 | } 55 | 56 | fn main() { 57 | let hello = String::from("Hello World"); 58 | let vec = vec![1,2,3]; 59 | let point = Point { x: 1, y: 2}; 60 | } 61 | ``` 62 | 63 | --- 64 | 65 | ## \#[derive(Debug)] 66 | 67 | ```rust 68 | #[derive(Debug)] 69 | struct Point { 70 | x: i32, 71 | y: i32 72 | } 73 | 74 | fn main() { 75 | let point = Box::new(Point { x: 1, y: 2}); 76 | println!("{:?}", point); 77 | } 78 | ``` 79 | 80 | Works for all data structures. -------------------------------------------------------------------------------- /presentation/chapters/en-US/macros.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/macros.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/match.chapter: -------------------------------------------------------------------------------- 1 | # Control Flow With Match 2 | 3 | --- 4 | 5 | Use `match` to check the variants of Enums. 6 | 7 | --- 8 | 9 | ```rust 10 | fn main() { 11 | let args = std::env::args; 12 | 13 | match args.at(1) { 14 | Some(arg) => { println!("Submitted Argument: {}", arg)}, 15 | None => { println!("No Argument submitted!") } 16 | } 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ```rust 23 | fn main() { 24 | let maybe_file = std::fs::File::open("Is not there!"); 25 | 26 | match maybe_file { 27 | Ok(f) => { println!("File opened! Debug: {:?}", f) }, 28 | Err(e) => { println!("File not opened! Error: {:?}", e) } 29 | } 30 | } 31 | ``` 32 | 33 | --- 34 | 35 | Matches must cover all variants. 36 | 37 | --- 38 | 39 | ## Ignore Other Variants 40 | 41 | ```rust 42 | fn main() { 43 | let maybe_file = std::fs::File::open("Is not there!"); 44 | 45 | match maybe_file { 46 | Err(e) => { println!("File not opened! Error: {:?}", e) } 47 | _ => {} 48 | } 49 | } 50 | ``` 51 | 52 | --- 53 | 54 | Results have a special marking: They must not be ignored! 55 | 56 | ```rust 57 | fn main() { 58 | let maybe_file = std::fs::File::open("Is not there!"); 59 | } 60 | ``` 61 | 62 | Solution: Match or pass along. 63 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/memory-considerations.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/memory-considerations.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/mutability.chapter: -------------------------------------------------------------------------------- 1 | # Mutability 2 | 3 | --- 4 | 5 | Modern programming languages differ in their attitude towards data mutability. 6 | 7 | Where does Rust land? 8 | 9 | --- 10 | 11 | ## An Example 12 | 13 | ```rust 14 | fn main() { 15 | let answer = 42; 16 | answer = 32; 17 | } 18 | ``` 19 | 20 | --- 21 | 22 | ## Correct 23 | 24 | ```rust 25 | fn main() { 26 | let mut answer = 42; 27 | answer = 32; 28 | } 29 | ``` 30 | 31 | --- 32 | 33 | In Rust data mutability must be declared. 34 | 35 | Mutability is always apparent from reading the code. 36 | 37 | --- 38 | 39 | Mutability is fundamental to Rust and is a common consideration. -------------------------------------------------------------------------------- /presentation/chapters/en-US/overview.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/overview.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/ownership.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/ownership.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/send-and-sync.chapter: -------------------------------------------------------------------------------- 1 | # Send & Sync 2 | 3 | --- 4 | 5 | There are two special traits in Rust for concurrency semantics. 6 | 7 | * `Send` marks a structure safe to *send* between threads. 8 | * `Sync` marks a structure safe to *share* between threads. 9 | + (`&T` is `Send`) 10 | 11 | --- 12 | 13 | These traits are what Rust uses to prevent data races. 14 | 15 | They are *automatically derived* for all types if appropriate. 16 | 17 | --- 18 | 19 | ## Automatically Derived 20 | 21 | ```rust 22 | use std::thread; 23 | 24 | #[derive(Debug)] 25 | struct Thing; 26 | 27 | // Can send between threads! 28 | fn main() { 29 | let thing = Thing; 30 | 31 | thread::spawn(move || { 32 | println!("{:?}", thing); 33 | }).join(); 34 | } 35 | ``` 36 | 37 | --- 38 | 39 | There are some notable types which are not `Send` or `Sync`. 40 | 41 | Such as `Rc`, raw pointers, and `UnsafeCell`. 42 | 43 | --- 44 | 45 | ## Example: `Rc` 46 | 47 | ```rust 48 | use std::rc::Rc; 49 | use std::thread; 50 | 51 | // Does not work! 52 | fn main() { 53 | let only_one_thread = Rc::new(true); 54 | 55 | thread::spawn(move || { 56 | println!("{:?}", only_one_thread); 57 | }).join(); 58 | } 59 | ``` 60 | 61 | --- 62 | 63 | ## Example: `Rc` 64 | 65 | ``` 66 | error[E0277]: the trait bound `std::rc::Rc: std::marker::Send` is not satisfied 67 | --> :7:5 68 | | 69 | 7 | thread::spawn(move || { 70 | | ^^^^^^^^^^^^^ the trait `std::marker::Send` is not implemented for `std::rc::Rc` 71 | ``` 72 | 73 | --- 74 | 75 | ## Implementing 76 | 77 | It's possible to add the implementation of `Send` and `Sync` to a type. 78 | 79 | ```rust 80 | struct Thing(*mut String); 81 | 82 | unsafe impl Send for Thing {} 83 | unsafe impl Sync for Thing {} 84 | ``` 85 | 86 | In these cases, the task of thread safety is left to the implementor. 87 | 88 | --- 89 | 90 | ## Relationships 91 | 92 | If a type implements both `Sync` and `Copy` then it can also implement `Send`. 93 | 94 | --- 95 | 96 | ## Relationships 97 | 98 | A type `&T` can implement `Send` if the type `T` also implements `Send`. 99 | 100 | ```rust 101 | unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} 102 | ``` 103 | 104 | --- 105 | 106 | ## Relationships 107 | 108 | A type `&mut T` can implement `Send` if the type `T` also implements `Send`. 109 | 110 | ```rust 111 | unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} 112 | ``` 113 | 114 | --- 115 | 116 | ## Consequences 117 | 118 | What are the consequences of having `Send` and `Sync`? 119 | 120 | --- 121 | 122 | ## Consequences 123 | 124 | Carrying this information at the type system level allows driving data race bugs down to a *compile time* level. 125 | 126 | Preventing this error class from reaching production systems. 127 | 128 | 129 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/smart-pointers.chapter: -------------------------------------------------------------------------------- 1 | # Special Pointers in Rust 2 | 3 | --- 4 | 5 | Rust offers several special pointers to handle different scenarios. 6 | 7 | They all have something in common: They are managed by ownership. 8 | 9 | --- 10 | 11 | ## `std::rc::Rc` 12 | 13 | Runtime reference counted within a thread. 14 | 15 | ```rust 16 | use std::rc::Rc; 17 | 18 | struct Point { 19 | x: i32, 20 | y: i32, 21 | } 22 | 23 | fn main() { 24 | let rced_point = Rc::new(Point { x: 1, y: 1}); 25 | let first_handle = rced_point.clone(); 26 | let second_handle = rced_point.clone(); 27 | } 28 | ``` 29 | 30 | --- 31 | 32 | ## Semantics 33 | 34 | * `Rc` is a handle on the contained data 35 | * The handle can be cloned 36 | * If the last handle drops, drop the data as well 37 | * `Rc` implements `Deref` 38 | 39 | --- 40 | 41 | ## `std::rc::Weak` 42 | 43 | Weak pointer to data. 44 | 45 | ```rust 46 | use std::rc::Rc; 47 | 48 | struct Point { 49 | x: i32, 50 | y: i32, 51 | } 52 | 53 | fn main() { 54 | let rced_point = Rc::new(Point { x: 1, y: 1}); 55 | let first_handle = rced_point.clone(); 56 | let weak = Rc::downgrade(first_handle); 57 | } 58 | ``` 59 | 60 | --- 61 | 62 | ## Semantics 63 | 64 | * Similar to `Rc`, however the existence of the data is not guaranteed 65 | * Single Threaded: The data is guaranteed to be available over the time of an operation 66 | * Is _not_ automatically dereferenced 67 | * `Rc` circles are memory leaks, weak pointers prevent that 68 | 69 | --- 70 | 71 | ## Use 72 | 73 | * Frequently used in data structures that require complex cross references 74 | * Higher runtime costs for more flexibility 75 | 76 | --- 77 | 78 | ## `std::sync::Arc` 79 | 80 | A more expensive `Rc` which works across thread boundaries since an atomic counter is used for incrementing. 81 | 82 | --- 83 | 84 | ## Remark 85 | 86 | Do not use `Arc` on a hunch. `rustc` rejects code using `Rc` over thread boundaries. 87 | 88 | --- 89 | 90 | ## `std::borrow::Cow` 91 | 92 | 93 | * Copy-on-write 94 | * Abstracts over Borrowing and Ownership 95 | * Clones Data only when necessary 96 | * https://doc.rust-lang.org/std/borrow/enum.Cow.html#examples 97 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/std-lib-tour.chapter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/chapters/en-US/std-lib-tour.chapter -------------------------------------------------------------------------------- /presentation/chapters/en-US/usage-examples.chapter: -------------------------------------------------------------------------------- 1 | # Usage examples 2 | 3 | --- 4 | 5 | ## Example 6 | 7 |
8 | 9 | --- 10 | 11 | ## SVG 12 | 13 |
14 | +------+ top
15 | |      |
16 | |      |
17 | +------+ bottom
18 | 
19 | -------------------------------------------------------------------------------- /presentation/chapters/en-US/working-with-nightly.chapter: -------------------------------------------------------------------------------- 1 | # Working With Nightly 2 | 3 | --- 4 | 5 | ## Why? 6 | 7 | * Dependencies may require nightly 8 | * Compile times and error messages are sometimes better (sometimes not) 9 | * There are several features which are not yet stable 10 | * Compiler plugins 11 | 12 | --- 13 | 14 | ## Recent Changes 15 | 16 | In [Rust 1.15](https://blog.rust-lang.org/2017/02/02/Rust-1.15.html) the 'custom derive' feature was made stable. 17 | 18 | This was for many projects the only reason to be using nightly. 19 | 20 | It is expected that the number of packages requiring nightly will significantly decrease soon. 21 | 22 | --- 23 | 24 | ## Using Nightly 25 | 26 | Use `rustup` to override the version used in a specific directory. 27 | 28 | ```bash 29 | cd /nightly_project 30 | rustup override set nightly 31 | ``` 32 | 33 | --- 34 | 35 | ## Features 36 | 37 | Features are gated behind "Feature Flags" which are enabled project wide. 38 | 39 | Some examples: 40 | 41 | * `asm` which provides inline assembly support 42 | * `no_std` which disables implict `extern crate std` 43 | * `inclusive_range`, similar to the stable `exclusive_range` 44 | 45 | --- 46 | 47 | ## Enabling Features 48 | 49 | To enable a feature, add the following line into `src/main.rs` (for executables), or`src/lib.rs` (for libraries): 50 | 51 | ```rust 52 | #![feature(asm, no_std)] 53 | ``` 54 | 55 | --- 56 | 57 | ## Compiler Plugins 58 | 59 | Compiler Plugins add additional capabilities to Rust. For example: 60 | 61 | * (Previously) custom derive 62 | * Linters 63 | * Libraries like [`regex_macros`](https://github.com/rust-lang/regex#usage-regex-compiler-plugin) 64 | 65 | --- 66 | 67 | ## Enabling Compiler Plugins 68 | 69 | To enable a compiler plugin add the following line into `src/main.rs` (for executables), or`src/lib.rs` (for libraries): 70 | 71 | ```rust 72 | #![plugin(some_plugin)] 73 | ``` 74 | -------------------------------------------------------------------------------- /presentation/components/headjs/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "headjs", 3 | "description": "HeadJS: Responsive Design, Feature Detections & Asset Loading. The only script in your ", 4 | "version": "1.0.3", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Tero Piirainen" 9 | }, 10 | { 11 | "name": "Robert Hoffmann" 12 | } 13 | ], 14 | "homepage ": "http://headjs.com", 15 | "main": [ 16 | "./dist/1.0.0/head.min.js", 17 | "./dist/1.0.0/head.min.js.map", 18 | "./dist/1.0.0/changelog.txt" 19 | ], 20 | "ignore": [ 21 | "**", 22 | "!/dist/1.0.0/*.js", 23 | "!/dist/1.0.0/*.map", 24 | "!/dist/1.0.0/*.txt" 25 | ], 26 | "directory": "public/scripts", 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/headjs/headjs.git" 30 | }, 31 | "keywords": [ 32 | "loader", 33 | "require", 34 | "polyfill", 35 | "html5", 36 | "css3", 37 | "feature", 38 | "responsive" 39 | ], 40 | "homepage": "https://github.com/headjs/headjs", 41 | "_release": "1.0.3", 42 | "_resolution": { 43 | "type": "version", 44 | "tag": "v1.0.3", 45 | "commit": "edc8427191a633d80e7372c49e6d28a098be766f" 46 | }, 47 | "_source": "https://github.com/headjs/headjs.git", 48 | "_target": "~1.0.3", 49 | "_originalSource": "headjs" 50 | } -------------------------------------------------------------------------------- /presentation/components/headjs/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "headjs", 3 | "description": "HeadJS: Responsive Design, Feature Detections & Asset Loading. The only script in your ", 4 | "version": "1.0.3", 5 | "license" : "MIT", 6 | "authors": [ 7 | {"name": "Tero Piirainen"}, 8 | {"name": "Robert Hoffmann"} 9 | ], 10 | "homepage " : "http://headjs.com", 11 | "main" : ["./dist/1.0.0/head.min.js","./dist/1.0.0/head.min.js.map","./dist/1.0.0/changelog.txt"], 12 | "ignore": [ 13 | "**", 14 | "!/dist/1.0.0/*.js", 15 | "!/dist/1.0.0/*.map", 16 | "!/dist/1.0.0/*.txt" 17 | ], 18 | "directory": "public/scripts", 19 | "repository": { 20 | "type": "git", "url": "git://github.com/headjs/headjs.git" 21 | }, 22 | "keywords": [ 23 | "loader", 24 | "require", 25 | "polyfill", 26 | "html5", 27 | "css3", 28 | "feature", 29 | "responsive" 30 | ] 31 | } -------------------------------------------------------------------------------- /presentation/components/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "version": "2.1.4", 4 | "main": "dist/jquery.js", 5 | "license": "MIT", 6 | "ignore": [ 7 | "**/.*", 8 | "build", 9 | "dist/cdn", 10 | "speed", 11 | "test", 12 | "*.md", 13 | "AUTHORS.txt", 14 | "Gruntfile.js", 15 | "package.json" 16 | ], 17 | "devDependencies": { 18 | "sizzle": "2.1.1-jquery.2.1.2", 19 | "requirejs": "2.1.10", 20 | "qunit": "1.14.0", 21 | "sinon": "1.8.1" 22 | }, 23 | "keywords": [ 24 | "jquery", 25 | "javascript", 26 | "library" 27 | ], 28 | "homepage": "https://github.com/jquery/jquery-dist", 29 | "_release": "2.1.4", 30 | "_resolution": { 31 | "type": "version", 32 | "tag": "2.1.4", 33 | "commit": "7751e69b615c6eca6f783a81e292a55725af6b85" 34 | }, 35 | "_source": "https://github.com/jquery/jquery-dist.git", 36 | "_target": "~2.1.4", 37 | "_originalSource": "jquery" 38 | } -------------------------------------------------------------------------------- /presentation/components/jquery/MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2014 jQuery Foundation and other contributors 2 | http://jquery.com/ 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /presentation/components/jquery/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "version": "2.1.4", 4 | "main": "dist/jquery.js", 5 | "license": "MIT", 6 | "ignore": [ 7 | "**/.*", 8 | "build", 9 | "dist/cdn", 10 | "speed", 11 | "test", 12 | "*.md", 13 | "AUTHORS.txt", 14 | "Gruntfile.js", 15 | "package.json" 16 | ], 17 | "devDependencies": { 18 | "sizzle": "2.1.1-jquery.2.1.2", 19 | "requirejs": "2.1.10", 20 | "qunit": "1.14.0", 21 | "sinon": "1.8.1" 22 | }, 23 | "keywords": [ 24 | "jquery", 25 | "javascript", 26 | "library" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /presentation/components/jquery/src/ajax/jsonp.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "../core", 3 | "./var/nonce", 4 | "./var/rquery", 5 | "../ajax" 6 | ], function( jQuery, nonce, rquery ) { 7 | 8 | var oldCallbacks = [], 9 | rjsonp = /(=)\?(?=&|$)|\?\?/; 10 | 11 | // Default jsonp settings 12 | jQuery.ajaxSetup({ 13 | jsonp: "callback", 14 | jsonpCallback: function() { 15 | var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 16 | this[ callback ] = true; 17 | return callback; 18 | } 19 | }); 20 | 21 | // Detect, normalize options and install callbacks for jsonp requests 22 | jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 23 | 24 | var callbackName, overwritten, responseContainer, 25 | jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 26 | "url" : 27 | typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" 28 | ); 29 | 30 | // Handle iff the expected data type is "jsonp" or we have a parameter to set 31 | if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 32 | 33 | // Get callback name, remembering preexisting value associated with it 34 | callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? 35 | s.jsonpCallback() : 36 | s.jsonpCallback; 37 | 38 | // Insert callback into url or form data 39 | if ( jsonProp ) { 40 | s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 41 | } else if ( s.jsonp !== false ) { 42 | s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 43 | } 44 | 45 | // Use data converter to retrieve json after script execution 46 | s.converters["script json"] = function() { 47 | if ( !responseContainer ) { 48 | jQuery.error( callbackName + " was not called" ); 49 | } 50 | return responseContainer[ 0 ]; 51 | }; 52 | 53 | // force json dataType 54 | s.dataTypes[ 0 ] = "json"; 55 | 56 | // Install callback 57 | overwritten = window[ callbackName ]; 58 | window[ callbackName ] = function() { 59 | responseContainer = arguments; 60 | }; 61 | 62 | // Clean-up function (fires after converters) 63 | jqXHR.always(function() { 64 | // Restore preexisting value 65 | window[ callbackName ] = overwritten; 66 | 67 | // Save back as free 68 | if ( s[ callbackName ] ) { 69 | // make sure that re-using the options doesn't screw things around 70 | s.jsonpCallback = originalSettings.jsonpCallback; 71 | 72 | // save the callback name for future use 73 | oldCallbacks.push( callbackName ); 74 | } 75 | 76 | // Call if it was a function and we have a response 77 | if ( responseContainer && jQuery.isFunction( overwritten ) ) { 78 | overwritten( responseContainer[ 0 ] ); 79 | } 80 | 81 | responseContainer = overwritten = undefined; 82 | }); 83 | 84 | // Delegate to script 85 | return "script"; 86 | } 87 | }); 88 | 89 | }); 90 | -------------------------------------------------------------------------------- /presentation/components/jquery/src/ajax/load.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "../core", 3 | "../core/parseHTML", 4 | "../ajax", 5 | "../traversing", 6 | "../manipulation", 7 | "../selector", 8 | // Optional event/alias dependency 9 | "../event/alias" 10 | ], function( jQuery ) { 11 | 12 | // Keep a copy of the old load method 13 | var _load = jQuery.fn.load; 14 | 15 | /** 16 | * Load a url into a page 17 | */ 18 | jQuery.fn.load = function( url, params, callback ) { 19 | if ( typeof url !== "string" && _load ) { 20 | return _load.apply( this, arguments ); 21 | } 22 | 23 | var selector, type, response, 24 | self = this, 25 | off = url.indexOf(" "); 26 | 27 | if ( off >= 0 ) { 28 | selector = jQuery.trim( url.slice( off ) ); 29 | url = url.slice( 0, off ); 30 | } 31 | 32 | // If it's a function 33 | if ( jQuery.isFunction( params ) ) { 34 | 35 | // We assume that it's the callback 36 | callback = params; 37 | params = undefined; 38 | 39 | // Otherwise, build a param string 40 | } else if ( params && typeof params === "object" ) { 41 | type = "POST"; 42 | } 43 | 44 | // If we have elements to modify, make the request 45 | if ( self.length > 0 ) { 46 | jQuery.ajax({ 47 | url: url, 48 | 49 | // if "type" variable is undefined, then "GET" method will be used 50 | type: type, 51 | dataType: "html", 52 | data: params 53 | }).done(function( responseText ) { 54 | 55 | // Save response for use in complete callback 56 | response = arguments; 57 | 58 | self.html( selector ? 59 | 60 | // If a selector was specified, locate the right elements in a dummy div 61 | // Exclude scripts to avoid IE 'Permission Denied' errors 62 | jQuery("
").append( jQuery.parseHTML( responseText ) ).find( selector ) : 63 | 64 | // Otherwise use the full result 65 | responseText ); 66 | 67 | }).complete( callback && function( jqXHR, status ) { 68 | self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); 69 | }); 70 | } 71 | 72 | return this; 73 | }; 74 | 75 | }); 76 | -------------------------------------------------------------------------------- /presentation/components/jquery/src/ajax/parseJSON.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "../core" 3 | ], function( jQuery ) { 4 | 5 | // Support: Android 2.3 6 | // Workaround failure to string-cast null input 7 | jQuery.parseJSON = function( data ) { 8 | return JSON.parse( data + "" ); 9 | }; 10 | 11 | return jQuery.parseJSON; 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /presentation/components/jquery/src/ajax/parseXML.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "../core" 3 | ], function( jQuery ) { 4 | 5 | // Cross-browser xml parsing 6 | jQuery.parseXML = function( data ) { 7 | var xml, tmp; 8 | if ( !data || typeof data !== "string" ) { 9 | return null; 10 | } 11 | 12 | // Support: IE9 13 | try { 14 | tmp = new DOMParser(); 15 | xml = tmp.parseFromString( data, "text/xml" ); 16 | } catch ( e ) { 17 | xml = undefined; 18 | } 19 | 20 | if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 21 | jQuery.error( "Invalid XML: " + data ); 22 | } 23 | return xml; 24 | }; 25 | 26 | return jQuery.parseXML; 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /presentation/components/jquery/src/ajax/script.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "../core", 3 | "../ajax" 4 | ], function( jQuery ) { 5 | 6 | // Install script dataType 7 | jQuery.ajaxSetup({ 8 | accepts: { 9 | script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 10 | }, 11 | contents: { 12 | script: /(?:java|ecma)script/ 13 | }, 14 | converters: { 15 | "text script": function( text ) { 16 | jQuery.globalEval( text ); 17 | return text; 18 | } 19 | } 20 | }); 21 | 22 | // Handle cache's special case and crossDomain 23 | jQuery.ajaxPrefilter( "script", function( s ) { 24 | if ( s.cache === undefined ) { 25 | s.cache = false; 26 | } 27 | if ( s.crossDomain ) { 28 | s.type = "GET"; 29 | } 30 | }); 31 | 32 | // Bind script tag hack transport 33 | jQuery.ajaxTransport( "script", function( s ) { 34 | // This transport only deals with cross domain requests 35 | if ( s.crossDomain ) { 36 | var script, callback; 37 | return { 38 | send: function( _, complete ) { 39 | script = jQuery(" 23 | 24 | 25 |
26 |
27 |
Slide 1
28 |
Slide 2
29 |
30 |
31 | 32 | 33 | 34 | 35 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/css/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #3f3f3f; 13 | color: #dcdcdc; 14 | } 15 | 16 | .hljs-keyword, 17 | .hljs-selector-tag, 18 | .hljs-tag { 19 | color: #e3ceab; 20 | } 21 | 22 | .hljs-template-tag { 23 | color: #dcdcdc; 24 | } 25 | 26 | .hljs-number { 27 | color: #8cd0d3; 28 | } 29 | 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-attribute { 33 | color: #efdcbc; 34 | } 35 | 36 | .hljs-literal { 37 | color: #efefaf; 38 | } 39 | 40 | .hljs-subst { 41 | color: #8f8f8f; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-name, 46 | .hljs-selector-id, 47 | .hljs-selector-class, 48 | .hljs-section, 49 | .hljs-type { 50 | color: #efef8f; 51 | } 52 | 53 | .hljs-symbol, 54 | .hljs-bullet, 55 | .hljs-link { 56 | color: #dca3a3; 57 | } 58 | 59 | .hljs-deletion, 60 | .hljs-string, 61 | .hljs-built_in, 62 | .hljs-builtin-name { 63 | color: #cc9393; 64 | } 65 | 66 | .hljs-addition, 67 | .hljs-comment, 68 | .hljs-quote, 69 | .hljs-meta { 70 | color: #7f9f7f; 71 | } 72 | 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | 78 | .hljs-strong { 79 | font-weight: bold; 80 | } 81 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/league-gothic/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License (OFL) 2 | http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/league-gothic/league-gothic.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'League Gothic'; 3 | src: url('league-gothic.eot'); 4 | src: url('league-gothic.eot?#iefix') format('embedded-opentype'), 5 | url('league-gothic.woff') format('woff'), 6 | url('league-gothic.ttf') format('truetype'); 7 | 8 | font-weight: normal; 9 | font-style: normal; 10 | } -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/league-gothic/league-gothic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/league-gothic/league-gothic.eot -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/league-gothic/league-gothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/league-gothic/league-gothic.ttf -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/league-gothic/league-gothic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/league-gothic/league-gothic.woff -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.eot -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.ttf -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.woff -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.eot -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.ttf -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.woff -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.eot -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.ttf -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.woff -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/font/source-sans-pro/source-sans-pro.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | src: url('source-sans-pro-regular.eot'); 4 | src: url('source-sans-pro-regular.eot?#iefix') format('embedded-opentype'), 5 | url('source-sans-pro-regular.woff') format('woff'), 6 | url('source-sans-pro-regular.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: 'Source Sans Pro'; 13 | src: url('source-sans-pro-italic.eot'); 14 | src: url('source-sans-pro-italic.eot?#iefix') format('embedded-opentype'), 15 | url('source-sans-pro-italic.woff') format('woff'), 16 | url('source-sans-pro-italic.ttf') format('truetype'); 17 | font-weight: normal; 18 | font-style: italic; 19 | } 20 | 21 | @font-face { 22 | font-family: 'Source Sans Pro'; 23 | src: url('source-sans-pro-semibold.eot'); 24 | src: url('source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'), 25 | url('source-sans-pro-semibold.woff') format('woff'), 26 | url('source-sans-pro-semibold.ttf') format('truetype'); 27 | font-weight: 600; 28 | font-style: normal; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Source Sans Pro'; 33 | src: url('source-sans-pro-semibolditalic.eot'); 34 | src: url('source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'), 35 | url('source-sans-pro-semibolditalic.woff') format('woff'), 36 | url('source-sans-pro-semibolditalic.ttf') format('truetype'); 37 | font-weight: 600; 38 | font-style: italic; 39 | } -------------------------------------------------------------------------------- /presentation/components/reveal.js/lib/js/classList.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 2 | if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;pbody{font-family: sans-serif;}

reveal.js multiplex server.

Generate token'); 38 | res.end(); 39 | }); 40 | stream.on('readable', function() { 41 | stream.pipe(res); 42 | }); 43 | }); 44 | 45 | app.get("/token", function(req,res) { 46 | var ts = new Date().getTime(); 47 | var rand = Math.floor(Math.random()*9999999); 48 | var secret = ts.toString() + rand.toString(); 49 | res.send({secret: secret, socketId: createHash(secret)}); 50 | }); 51 | 52 | var createHash = function(secret) { 53 | var cipher = crypto.createCipher('blowfish', secret); 54 | return(cipher.final('hex')); 55 | }; 56 | 57 | // Actually listen 58 | server.listen( opts.port || null ); 59 | 60 | var brown = '\033[33m', 61 | green = '\033[32m', 62 | reset = '\033[0m'; 63 | 64 | console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset ); -------------------------------------------------------------------------------- /presentation/components/reveal.js/plugin/multiplex/master.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // Don't emit events from inside of notes windows 4 | if ( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var multiplex = Reveal.getConfig().multiplex; 7 | 8 | var socket = io.connect( multiplex.url ); 9 | 10 | function post() { 11 | 12 | var messageData = { 13 | state: Reveal.getState(), 14 | secret: multiplex.secret, 15 | socketId: multiplex.id 16 | }; 17 | 18 | socket.emit( 'multiplex-statechanged', messageData ); 19 | 20 | }; 21 | 22 | // Monitor events that trigger a change in state 23 | Reveal.addEventListener( 'slidechanged', post ); 24 | Reveal.addEventListener( 'fragmentshown', post ); 25 | Reveal.addEventListener( 'fragmenthidden', post ); 26 | Reveal.addEventListener( 'overviewhidden', post ); 27 | Reveal.addEventListener( 'overviewshown', post ); 28 | Reveal.addEventListener( 'paused', post ); 29 | Reveal.addEventListener( 'resumed', post ); 30 | 31 | }()); -------------------------------------------------------------------------------- /presentation/components/reveal.js/plugin/multiplex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reveal-js-multiplex", 3 | "version": "1.0.0", 4 | "description": "reveal.js multiplex server", 5 | "homepage": "http://lab.hakim.se/reveal-js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "engines": { 10 | "node": "~4.1.1" 11 | }, 12 | "dependencies": { 13 | "express": "~4.13.3", 14 | "grunt-cli": "~0.1.13", 15 | "mustache": "~2.2.1", 16 | "socket.io": "~1.3.7" 17 | }, 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/plugin/notes-server/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // don't emit events from inside the previews themselves 4 | if( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var socket = io.connect( window.location.origin ), 7 | socketId = Math.random().toString().slice( 2 ); 8 | 9 | console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId ); 10 | 11 | window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId ); 12 | 13 | /** 14 | * Posts the current slide data to the notes window 15 | */ 16 | function post() { 17 | 18 | var slideElement = Reveal.getCurrentSlide(), 19 | notesElement = slideElement.querySelector( 'aside.notes' ); 20 | 21 | var messageData = { 22 | notes: '', 23 | markdown: false, 24 | socketId: socketId, 25 | state: Reveal.getState() 26 | }; 27 | 28 | // Look for notes defined in a slide attribute 29 | if( slideElement.hasAttribute( 'data-notes' ) ) { 30 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 31 | } 32 | 33 | // Look for notes defined in an aside element 34 | if( notesElement ) { 35 | messageData.notes = notesElement.innerHTML; 36 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 37 | } 38 | 39 | socket.emit( 'statechanged', messageData ); 40 | 41 | } 42 | 43 | // When a new notes window connects, post our current state 44 | socket.on( 'new-subscriber', function( data ) { 45 | post(); 46 | } ); 47 | 48 | // When the state changes from inside of the speaker view 49 | socket.on( 'statechanged-speaker', function( data ) { 50 | Reveal.setState( data.state ); 51 | } ); 52 | 53 | // Monitor events that trigger a change in state 54 | Reveal.addEventListener( 'slidechanged', post ); 55 | Reveal.addEventListener( 'fragmentshown', post ); 56 | Reveal.addEventListener( 'fragmenthidden', post ); 57 | Reveal.addEventListener( 'overviewhidden', post ); 58 | Reveal.addEventListener( 'overviewshown', post ); 59 | Reveal.addEventListener( 'paused', post ); 60 | Reveal.addEventListener( 'resumed', post ); 61 | 62 | // Post the initial state 63 | post(); 64 | 65 | }()); 66 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/plugin/notes-server/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var express = require('express'); 3 | var fs = require('fs'); 4 | var io = require('socket.io'); 5 | var Mustache = require('mustache'); 6 | 7 | var app = express(); 8 | var staticDir = express.static; 9 | var server = http.createServer(app); 10 | 11 | io = io(server); 12 | 13 | var opts = { 14 | port : 1947, 15 | baseDir : __dirname + '/../../' 16 | }; 17 | 18 | io.on( 'connection', function( socket ) { 19 | 20 | socket.on( 'new-subscriber', function( data ) { 21 | socket.broadcast.emit( 'new-subscriber', data ); 22 | }); 23 | 24 | socket.on( 'statechanged', function( data ) { 25 | delete data.state.overview; 26 | socket.broadcast.emit( 'statechanged', data ); 27 | }); 28 | 29 | socket.on( 'statechanged-speaker', function( data ) { 30 | delete data.state.overview; 31 | socket.broadcast.emit( 'statechanged-speaker', data ); 32 | }); 33 | 34 | }); 35 | 36 | [ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) { 37 | app.use( '/' + dir, staticDir( opts.baseDir + dir ) ); 38 | }); 39 | 40 | app.get('/', function( req, res ) { 41 | 42 | res.writeHead( 200, { 'Content-Type': 'text/html' } ); 43 | fs.createReadStream( opts.baseDir + '/index.html' ).pipe( res ); 44 | 45 | }); 46 | 47 | app.get( '/notes/:socketId', function( req, res ) { 48 | 49 | fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) { 50 | res.send( Mustache.to_html( data.toString(), { 51 | socketId : req.params.socketId 52 | })); 53 | }); 54 | 55 | }); 56 | 57 | // Actually listen 58 | server.listen( opts.port || null ); 59 | 60 | var brown = '\033[33m', 61 | green = '\033[32m', 62 | reset = '\033[0m'; 63 | 64 | var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : '' ); 65 | 66 | console.log( brown + 'reveal.js - Speaker Notes' + reset ); 67 | console.log( '1. Open the slides at ' + green + slidesLocation + reset ); 68 | console.log( '2. Click on the link in your JS console to go to the notes page' ); 69 | console.log( '3. Advance through your slides and your notes will advance automatically' ); 70 | -------------------------------------------------------------------------------- /presentation/components/reveal.js/plugin/print-pdf/print-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * phantomjs script for printing presentations to PDF. 3 | * 4 | * Example: 5 | * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf 6 | * 7 | * By Manuel Bieh (https://github.com/manuelbieh) 8 | */ 9 | 10 | // html2pdf.js 11 | var page = new WebPage(); 12 | var system = require( 'system' ); 13 | 14 | var slideWidth = system.args[3] ? system.args[3].split( 'x' )[0] : 960; 15 | var slideHeight = system.args[3] ? system.args[3].split( 'x' )[1] : 700; 16 | 17 | page.viewportSize = { 18 | width: slideWidth, 19 | height: slideHeight 20 | }; 21 | 22 | // TODO 23 | // Something is wrong with these config values. An input 24 | // paper width of 1920px actually results in a 756px wide 25 | // PDF. 26 | page.paperSize = { 27 | width: Math.round( slideWidth * 2 ), 28 | height: Math.round( slideHeight * 2 ), 29 | border: 0 30 | }; 31 | 32 | var inputFile = system.args[1] || 'index.html?print-pdf'; 33 | var outputFile = system.args[2] || 'slides.pdf'; 34 | 35 | if( outputFile.match( /\.pdf$/gi ) === null ) { 36 | outputFile += '.pdf'; 37 | } 38 | 39 | console.log( 'Printing PDF (Paper size: '+ page.paperSize.width + 'x' + page.paperSize.height +')' ); 40 | 41 | page.open( inputFile, function( status ) { 42 | window.setTimeout( function() { 43 | console.log( 'Printed successfully' ); 44 | page.render( outputFile ); 45 | phantom.exit(); 46 | }, 1000 ); 47 | } ); 48 | 49 | -------------------------------------------------------------------------------- /presentation/css/console.css: -------------------------------------------------------------------------------- 1 | .exec{ 2 | position: absolute; 3 | top: 0; 4 | right: 0; 5 | } 6 | .reset{ 7 | position: absolute; 8 | top: 0; 9 | left: 0; 10 | } 11 | .return{ 12 | overflow-y: scroll; 13 | max-height: 160px; 14 | display: block; 15 | } 16 | .btn{ 17 | background: #3498db; 18 | background-image: -webkit-linear-gradient(top, #3498db, #2980b9); 19 | background-image: -moz-linear-gradient(top, #3498db, #2980b9); 20 | background-image: -ms-linear-gradient(top, #3498db, #2980b9); 21 | background-image: -o-linear-gradient(top, #3498db, #2980b9); 22 | background-image: linear-gradient(to bottom, #3498db, #2980b9); 23 | -webkit-border-radius: 4; 24 | -moz-border-radius: 4; 25 | border-radius: 4px; 26 | border: none; 27 | color: #ffffff; 28 | padding: 4px 10px 4px 10px; 29 | text-decoration: none; 30 | cursor: pointer; 31 | font-weight: 600; 32 | } 33 | .btn:hover { 34 | background: #3cb0fd; 35 | background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db); 36 | background-image: -moz-linear-gradient(top, #3cb0fd, #3498db); 37 | background-image: -ms-linear-gradient(top, #3cb0fd, #3498db); 38 | background-image: -o-linear-gradient(top, #3cb0fd, #3498db); 39 | background-image: linear-gradient(to bottom, #3cb0fd, #3498db); 40 | text-decoration: none; 41 | } -------------------------------------------------------------------------------- /presentation/img/rust.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Asquera/rust-three-days-course/39c7a2a8f801947d365c7e5c368ba5ae56054857/presentation/img/rust.gif -------------------------------------------------------------------------------- /presentation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Rust in drei Tagen 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | 25 | 26 |
27 |
28 |
29 |
30 | 31 | 38 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /presentation/js/locale-selector.js: -------------------------------------------------------------------------------- 1 | const LocaleSelector = (function(){ 2 | const klass = function(){ 3 | this.initialize.apply(this, arguments); 4 | }; 5 | klass.prototype = { 6 | initialize: function(conf){ 7 | this.localeFiles = conf.locales || {}, 8 | this.defaultLocale = conf.default || "en-US", 9 | this.el = conf.el; 10 | this.templates = { 11 | slide: conf.templates.slide.content, 12 | localeSelector: conf.templates.selector.content 13 | }; 14 | this.reveal = conf.reveal; 15 | this.start(); 16 | }, 17 | start: function(){ 18 | const location = new URL(window.location); 19 | const locale = 20 | location.searchParams.get("locale") || this.defaultLocale; 21 | this.setLocale(locale, location); 22 | }, 23 | setLocale: function(locale, location){ 24 | location = location || new URL(window.location); 25 | locale = locale || this.defaultLocale; 26 | const md = this.localeFiles[locale]; 27 | if(md){ 28 | this.clearSlide(); 29 | this.setupSlide(md); 30 | } 31 | }, 32 | clearSlide: function(){ 33 | while(this.el.firstChild){ 34 | this.el.removeChild(this.el.firstChild); 35 | } 36 | }, 37 | setupSlide: function(md){ 38 | const fragment = document.importNode(this.templates.slide, true); 39 | this.el.appendChild(fragment); 40 | const slide = this.el.querySelector(".markdown-slide"); 41 | slide.dataset.markdown = md; 42 | this.render(); 43 | }, 44 | render: function(){ 45 | Reveal.initialize(this.reveal); 46 | const observer = new MutationObserver((records, observer) =>{ 47 | if(records.length > 0 && records[0].addedNodes){ 48 | this.addLocaleSelector(records[0].addedNodes[0]); 49 | observer.disconnect(); 50 | } 51 | }); 52 | observer.observe(this.el, {childList: true}); 53 | }, 54 | addLocaleSelector: function(slide){ 55 | const fragment = document.importNode(this.templates.localeSelector, true); 56 | slide.appendChild(fragment); 57 | const select = slide.querySelector("select"); 58 | select.addEventListener("change", e => { 59 | const locale = select.value; 60 | const location = new URL(window.location); 61 | if(locale.length > 0){ 62 | location.searchParams.set("locale", locale); 63 | window.location = location; 64 | } 65 | }); 66 | } 67 | }; 68 | 69 | klass.initialize = function(conf){ 70 | return new klass(conf); 71 | }; 72 | 73 | return klass; 74 | })(); 75 | -------------------------------------------------------------------------------- /presentation/js/playRust.js: -------------------------------------------------------------------------------- 1 | var buttons = '' + "\n"; 2 | var result = ''; 3 | 4 | function addButtons() { 5 | $('pre code.rust').each(function(i, block){ 6 | $(block).before(buttons); 7 | $(block).after(result); 8 | }); 9 | $('pre code.lang-rust').each(function(i, block){ 10 | $(block).before(buttons); 11 | $(block).after(result); 12 | }); 13 | $('.reset').each(function (n) { 14 | $(this).context._code = $(this).siblings('code').text(); 15 | }); 16 | $('.exec').click(function () { 17 | var target = $(this).siblings('.return'); 18 | target.html(''); 19 | var code = $(this).siblings('code').text(); 20 | var payload = {optimize:"0", version:"stable", code: code}; 21 | $.ajax({ 22 | url: 'https://play.rust-lang.org/evaluate.json', 23 | type: "POST", 24 | dataType: "json", 25 | data: JSON.stringify(payload), 26 | contentType: "application/json" 27 | }).done(function(result) { 28 | var output = formatOutput(result.result); 29 | console.log(output.compiler); 30 | target.html(output.output); 31 | }); 32 | }); 33 | $('.reset').click(function () { 34 | $(this).siblings('code').text($(this).context._code); 35 | hljs.highlightBlock($(this).siblings('code')[0]); 36 | }) 37 | $('.versionable').blur(function () { 38 | console.log('versioning comming soon') 39 | }); 40 | } 41 | formatOutput = function (output) { 42 | var parts = output.split(/\n/); 43 | var compiler = parts.shift(); 44 | return {compiler: compiler, output: parts.join('
')} 45 | } 46 | -------------------------------------------------------------------------------- /presentation/js/remote-code.js: -------------------------------------------------------------------------------- 1 | fetchAllCode = function(){ 2 | Array.prototype.slice.call(document.querySelectorAll('code[data-source]')).forEach(function(codeContainer){ 3 | var xhr = new XMLHttpRequest(); 4 | xhr.open("GET", codeContainer.dataset.source, true); 5 | xhr.overrideMimeType("text/plain; charset=x-user-defined"); 6 | xhr.onreadystatechange = function () { 7 | if (xhr.readyState == 4) { 8 | if (xhr.status == 200) { 9 | var code = document.createTextNode(xhr.responseText); 10 | codeContainer.appendChild(code); 11 | if(typeof(hljs) !== 'undefined') 12 | hljs.highlightBlock(codeContainer); 13 | } 14 | else 15 | console.error("Error while trying to get remote code"); 16 | } 17 | }; 18 | try { 19 | xhr.send(null); 20 | } catch (e) { 21 | console.error("XHR failed for " + url + ", " + e); 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /presentation/js/slideInit.js: -------------------------------------------------------------------------------- 1 | var urlParams = new URLSearchParams(window.location.search); 2 | var chapter; 3 | if (urlParams.has("chapter")) { 4 | chapter = urlParams.get("chapter"); 5 | } else { 6 | chapter = "intro"; 7 | } 8 | LocaleSelector.initialize({ 9 | templates: { 10 | slide: document.querySelector("#markdown-section"), 11 | selector: document.querySelector("#locale-selector") 12 | }, 13 | el: document.querySelector(".slides"), 14 | locales: { 15 | "en-US": "chapters/en-US/" + chapter + ".chapter", 16 | "de-DE": "chapters/de-DE/" + chapter + ".chapter" 17 | }, 18 | default: "de-DE", 19 | reveal: { 20 | history: true, 21 | dependencies: [ 22 | { src: 'components/reveal.js/plugin/markdown/marked.js' }, 23 | { src: 'components/reveal.js/plugin/markdown/markdown.js' }, 24 | { src: 'components/reveal.js/plugin/notes/notes.js', async: true }, 25 | { src: 'components/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { fetchAllCode(); hljs.initHighlightingOnLoad(); addButtons(); } }, 26 | { src: 'js/svgDrawings.js', async: true, callback: function() { drawSvgs() } } 27 | ] 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /presentation/js/svgDrawings.js: -------------------------------------------------------------------------------- 1 | 2 | function drawSvgs() { 3 | $('pre.diagram').each(function(i, block){ 4 | var svg = Module.process_string("demo", block.textContent, "rust diagram") 5 | var parent = block.parentNode; 6 | var svgElement = htmlToElement(svg); 7 | parent.removeChild(block); 8 | parent.appendChild(svgElement); 9 | }) 10 | } 11 | 12 | function htmlToElement(html) { 13 | var template = document.createElement('template'); 14 | template.innerHTML = html; 15 | return template.content.firstChild; 16 | } 17 | -------------------------------------------------------------------------------- /presentation/tasks/add-chapter.rsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rustscript 2 | 3 | #[macro_use] extern crate shells; 4 | use std::fs::File; 5 | 6 | let locales = ["de-DE", "en-US"]; 7 | let filename = std::env::args().nth(1).unwrap(); 8 | 9 | for locale in locales.iter() { 10 | let path = format!("chapters/{}/{}.chapter", locale, filename); 11 | File::create(&path).expect("File creation should succeed"); 12 | println!("Created {}", &path); 13 | } 14 | -------------------------------------------------------------------------------- /presentation/tasks/rename-chapter.rsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rustscript 2 | 3 | #[macro_use] extern crate shells; 4 | use std::fs::rename; 5 | 6 | let locales = ["de-DE", "en-US"]; 7 | let original = std::env::args().nth(1).unwrap(); 8 | let new = std::env::args().nth(2).unwrap(); 9 | 10 | for locale in locales.iter() { 11 | let originalpath = format!("chapters/{}/{}.chapter", locale, original); 12 | let newpath = format!("chapters/{}/{}.chapter", locale, new); 13 | rename(&originalpath, &newpath).expect("File renaming must be successful"); 14 | sh!("git rm {}", originalpath); 15 | println!("Renamed {} to {}", originalpath, newpath); 16 | } -------------------------------------------------------------------------------- /presentation/tasks/rename-chapters.rsc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rustscript 2 | 3 | #[macro_use] extern crate shells; 4 | 5 | extern crate glob; 6 | use glob::glob; 7 | 8 | use std::fs::rename; 9 | 10 | let locales = ["de-DE", "en-US"]; 11 | 12 | for locale in locales.iter() { 13 | let files = glob(format!("chapters/{}/*.md", locale).as_ref()).unwrap(); 14 | for file in files { 15 | let file = file.unwrap(); 16 | let file = file.to_string_lossy(); 17 | let new_name = format!("{}{}", &file.split(".").nth(0).unwrap(), ".chapter"); 18 | sh!("git mv {} {}", file, new_name); 19 | } 20 | } --------------------------------------------------------------------------------