2. Alternative Agenda
1 Introduction
2 Data Types
3 Memory Management
4 Control Flow
5 Behavior for Data Types
6 IDE Story and Corrosion
7 Conclusion
| 25.10.2018 | Rust and Eclipse2
4. 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018
* not as breaking as you might think
History and Development
| 25.10.2018 | Rust and Eclipse4
Started as hobby
project by Mozilla
employee
Graydon Hoare
First stable
version 1.0
The new
“2018 Edition”
with breaking
changes* will
be introduced
Since then new
stable release
every 6 weeks
Mozilla started
sponsoring the
project
Mozilla started
using Rust for
experimental
browser engine
Servo
5. Rust considers itself a “systems programming language”
Compiled to native code (compiler is LLVM frontend)
Motto: safe, fast, productive — pick three
Borrows ideas from…
C++ — zero cost abstractions, RAII
Haskell — ADTs, type classes, pattern matching, local type inference
ML — general syntax
Cyclone — safe manual memory management
Overview
| 25.10.2018 | Rust and Eclipse5
6. Production Users: https://www.rust-lang.org/en-US/friends.html
Some Common Uses Today
| 25.10.2018 | Rust and Eclipse6
Systems / Infrastructure
high performance,
low latency,
low memory overhead
requirements
WebAssembly libraries Embedded into C/C++
applications for safety
critical parts
Embedded into other
language runtimes for
performance critical
parts
$
Command line
applications
7. Future Application Domains
| 25.10.2018 | Rust and Eclipse7
IoT / Embedded Asynchronous
networking
services
Key crates (APIs) and language features in these domains are not yet stable,
though already usable today
8. RustConf 2018 Talk: Getting Somethig for Nothing:
https://www.youtube.com/watch?v=t99L3JHhLc0
Embedded Hardware Development with Rust:
https://www.youtube.com/watch?v=g25xsK3HKkE
Awesome Embedded Rust (Overview Doc):
https://github.com/rust-embedded/awesome-embedded-rust
IoT Embedded Entry Points
| 25.10.2018 | Rust and Eclipse8
9. rustup — Toolchain version / install manager
https://rustup.rs/
cargo — Build tool and package manager
Package registry: https://crates.io/
Several small helper tools (most triggered via cargo)
rustdoc — Creates HTML API documentation based on Markdown doc
comments; can run code examples as tests
rustfmt — Formats Rust code based on standardized formatting rules
rls — Language server for Rust (for IDE integrations); in preview
cargo-clippy — Rust linter; in preview
Tool Infrastructure
| 25.10.2018 | Rust and Eclipse9
10. ~$
...
~$
Created binary (application) `helloworld` project
~/helloworld$
Compiling helloworld v0.1.0 (file:///home/mbu/rust/helloworld)
Finished dev [unoptimized + debuginfo] target(s) in 1.71s
Running `target/debug/helloworld`
Hello, world!
First Steps (On Linux)
| 25.10.2018 | Rust and Eclipse10
curl https://sh.rustup.rs -sSf | sh
cargo new helloworld && cd helloworld
cargo run
Answer some questions
11. Closures
Panicking vs. Error Type
Crates, modules and visibility
Cargo and dependency management
Macros
Explicit lifetime annotations
…
⇨ For more details, please visit introduction materials listed at the end
Many Important Topics Not Covered (Due to Time Constraints)
| 25.10.2018 | Rust and Eclipse11
12. Buckle up: First Example
| 25.10.2018 | Rust and Eclipse12
source: https://cheezburger.com/9191857664
13. use std::env;
fn main() {
let first_arg : Option<String> = env::args().skip(1).next();
let world : &str = "World";
let greetee = match first_arg {
Some(ref name) => name,
None => world
};
println!("Hello {}!", greetee);
}
(Unnecessarily Complicated) Hello World Example
| 25.10.2018 | Rust and Eclipse13
https://play.rust-lang.org/?gist=70a7f42d53d8639013a80a1cc02db61b&version=stable&mode=debug&edition=2015
Module import
Typed variable declaration Iterator combinator
Pattern matching expression
Reference type
Inferred
type
Macro invocation
14. Example Function
| 25.10.2018 | Rust and Eclipse14
https://play.rust-lang.org/?gist=76da1cf5724dc605a5ef144cab0886bc&version=stable&mode=debug&edition=2015
fn get_name(default : String) -> String {
let first_arg = env::args().skip(1).next();
first_arg.map_or(default, |s : String| {
// upper case first letter
let (first_char, rest) = s.split_at(1);
first_char.to_uppercase() + rest
} )
}
Function signature, types cannot be inferred
Closure
Tuple
destructuring
No ; ⇒ returns value from expression
16. Unsigned Integers
u8, u16, u32, u64, u128
Example: let num = 42u8;
Signed Integers
i8, i16, i32, i64, i128
Example: let temperature = -20_i32;
Floating Point Types ( IEEE 754-2008 )
f32, f64
Example: let time = 0.11_f32;
Boolean
bool
Example: let t : bool = true;
Unit
() — the empty tuple, representing “nothing”
Example: fn main() -> () { return (); }
A Few Primitive Types
| 25.10.2018 | Rust and Eclipse16
https://play.rust-lang.org/?gist=1ec0b155c7a0d8ca07d9acc7536bcb10&version=stable&mode=debug&edition=2015
17. Pointer Sized Integers (Unsigned and Signed)
usize, isize
Example: let count : usize = 0xff;
Characters
char — 4 byte sized Unicode character
Example: let umbrella = '☂';
Never Type
! — No value (there is no instance), e.g. function that never returns
Example: fn forever() -> ! { loop {} }
More Primitive Types
https://play.rust-lang.org/?gist=b58a5b06d04a44d4f901d2720827332e&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse17
18. Array
[T;N]
Fixed size array; consecutively in memory
Example:
let bytes : [u8;3] = [0x20,0x34,0x32];
Slice
[T]
Dynamically sized window into arrays
Usually only used as reference type &[T]
Example:
let s : &[u8] = &bytes[1..];
Tuple
(T, U, ..)
Sequence of possibly differently typed elements
Example:
let two_nums : (u32,f32) = (42, 3.14);
Compound Primitive Types
| 25.10.2018 | Rust and Eclipse18
https://play.rust-lang.org/?gist=ae76b70fe36a85a937ff952896d3a7c9&version=stable&mode=debug&edition=2015
19. String and str are the most commonly used, but others exist e.g. for compatibility reasons
String Types
| 25.10.2018 | Rust and Eclipse19
https://www.rust-lang.org/en-US/faq.html#strings
Represents “Slice” type “Owned” type
UTF-8 string str String
OS-compatible string OsStr OsString
C-compatible string CStr CString
System path Path PathBuf
20. Are user defined Algebraic Data Types / Tagged Unions
Values of the type hold one variant and a (hidden) discriminator
Examples from standard library:
Example usage:
let os : Option<u32> = Option::Some(42);
Enums
pub enum Option<T> {
None,
Some(T)
}
pub enum Result<T, E> {
Ok(T),
Err(E),
}
| 25.10.2018 | Rust and Eclipse20
21. Custom data type for grouping named values
Example:
struct Caterpillar {
name : String,
hunger : u8
}
// initialization
let harry = Caterpillar {
name : String::from("Harry"),
hunger : 100
};
Structs
| 25.10.2018 | Rust and Eclipse21
https://play.rust-lang.org/?gist=1ad79162e684e94c189195fcdfcdd5b6&version=stable&mode=debug&edition=2015
23. Rust ensures safe manual memory management checked at compile time
No garbage collector; does not fundamentally need reference counting
The memory management is built around concepts of ownership and borrowing
Ownership can be transferred, original data is not accessible anymore afterwards
Basics
23 | 25.10.2018 | Rust and Eclipse
24. Example of Ownership and Immutable Borrowing
24
https://play.rust-lang.org/?gist=152e2b2060d8ddb5af99d9b8213e86a0&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse
let mut owned_c : Caterpillar =
Caterpillar { name : String::from("Harry"), hunger: 100 };
let borrowed_c : &Caterpillar = &owned_c;
let hunger = (*borrowed_c).hunger; // only read access
// actually * not needed most of the time, due to auto-deref
println!("{}", hunger);
25. Example of Ownership and Mutable Borrowing
25
https://play.rust-lang.org/?gist=152e2b2060d8ddb5af99d9b8213e86a0&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse
let mut owned_c : Caterpillar = Caterpillar { /* … */ };
let mutably_borrowed_c : &mut Caterpillar = &mut owned_c;
mutably_borrowed_c.hunger = 90; // look: auto-deref
26. Example of Transferring Ownership
26
https://play.rust-lang.org/?gist=152e2b2060d8ddb5af99d9b8213e86a0&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse
let mut owned_c : Caterpillar = Caterpillar { /* … */ };
let moved_c : Caterpillar = owned_c; // took ownership, but immutable now
27. IMHO: Biggest distinction from other (systems) programming languages
Its rules promise compile time memory safety and freedom from data races
Also: The Rust feature most new rusteaceans struggle with
The Borrow Checker
| 25.10.2018 | Rust and Eclipse27
28. Problems commonly associated with manual memory management:
Use after free (dangling pointer)
Double free
Not freeing memory (leak)
Buffer over- and underflow
Many of these problems can lead to safety & security issues
To its credit: C++ >=11 and Guidelines Support Library tackle some of the problems
The Borrow Checker: Problem Statement
| 25.10.2018 | Rust and Eclipse28
Prevented by Borrow Checker
Prevented by array implementation
and lack of raw pointers (in safe Rust)
29. #include <iostream>
#include <vector>
int main() {
std::vector<int> v {0};
int& e = v[0];
for(int i=1; i<5; i++) {
v.push_back(i);
}
std::cout << e;
return 0;
}
C++ Hidden Use After Free Example
| 25.10.2018 | Rust and Eclipse29
http://cpp.sh/2cpwg https://godbolt.org/z/WxcbO2
v
e
0 1 2 3 4
30. Single owner of every piece of memory at one time
When owner goes out of scope, memory is freed
References to owned memory can be “borrowed” (aliasing)
References must not outlive referenced memory (lifetimes)
Single exclusive access to memory, when access mutable
Or multiple immutable access at the same time; no mutable access
Some Important Borrow Checker Rules
| 25.10.2018 | Rust and Eclipse30
31. fn main() {
let mut v : Vec<i32> = vec![0];
let el : &i32 = &v[0];
for i in 1..=4 {
v.push(i);
}
println!("{}", el);
}
Example Violating Borrow Checker Rules
| 25.10.2018 | Rust and Eclipse31
https://play.rust-lang.org/?gist=8d3a9401792f6693f70de377bafa0694&version=stable&mode=debug&edition=2015
32. Example Compiler Output
32 | 25.10.2018 | Rust and Eclipse
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> srcmain.rs:29:3
|
26 | let el = &v[0];
| - immutable borrow occurs here
...
29 | v.push(i);
| ^ mutable borrow occurs here
...
33 | }
| - immutable borrow ends here
For more information about this error, try `rustc --explain E0502`.
error: Could not compile `testbin`.
To learn more, run the command again with --verbose.
33. use std::io::BufRead;
let mut lines = std::io::stdin().lock().lines();
while let Some(Ok(line)) = lines.next() {
println!("{}", line);
}
Example 2 Violating Borrow Checker Rules
33
https://play.rust-lang.org/?gist=7660f6853728d2cf7f48b7dd4970e6d6&version=stable&mode=debug&edition=2015
| 25.10.2018 | Präsentationstitel
34. Example 2 Compiler Output
34 | 25.10.2018 | Rust and Eclipse
error[E0597]: borrowed value does not live long enough
--> srcmain.rs:39:18
|
39 | let mut lines = std::io::stdin().lock().lines();
| ^^^^^^^^^^^^^^^^ - temporary value dropped here while still borrowed
| |
| temporary value does not live long enough
...
43 | }
| - temporary value needs to live until here
|
= note: consider using a `let` binding to increase its lifetime
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
35. RefCell<T> — Thread local dynamically checked exclusive mutable access
Mutex<T> — Thread safe dynamically checked exclusive mutable access
Rc<T> — Thread local shared ownership
Arc<T> — Thread safe shared ownership
Some Escape Hatches: Borrow Checker Rules at Runtime
| 25.10.2018 | Rust and Eclipse35
36. The standard library provides some basic types for keeping memory on the heap
Box<T> — Single element
must always hold a value, there is no null-pointer
Example: let foo : Box<f32> = Box::new(3.14);
String — Owned strings are always kept on the heap
Collections: Multiple elements on the heap; re-sizable
Vec<T>, VecDeque<T>, LinkedList<T>, BinaryHeap<T>, HashSet<T>, BTreeSet<T>,
HashMap<K,V>, BTreeMap<K,V>
Heap Memory
| 25.10.2018 | Rust and Eclipse36
https://play.rust-lang.org/?gist=c383e368b831c85cef0bf4af2935b15a&version=stable&mode=debug&edition=2015
39. If expressions
Match expressions
Loop expressions
For loops
While loops
Infinite loops
? Operator
Control Flow Overview
| 25.10.2018 | Rust and Eclipse39
40. Since Expression, can evaluate to a value
If let can be used for simple destructuring
Example:
let random : u64 =
my_very_unsafe_random_gen();
let output = if random % 2 == 0 {
"Heads"
} else {
"Tails"
};
println!("{}", output);
If Expressions
https://play.rust-lang.org/?gist=6dee066ba8ffb2ef067070b0600d4ef3&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse40
let java_home : Result<String, _> =
std::env::var("JAVA_HOME");
if let Ok(home_str) = java_home {
println!("Your JAVA_HOME is : {}",
home_str);
}
41. Match is similar to a switch in other languages, but over patterns
Can be used to de-structure structs, enums, tuples, arrays / slices
Match has to be exhaustive
Example:
let c : Caterpillar = construct_caterpillar();
let output = match c {
Caterpillar { ref name, .. } if name == "Harry" => String::from("Hi Harry!"),
Caterpillar { ref name, hunger: h @ 50...100 } => format!("Hi, {} you are {}% hungry!", name, h),
Caterpillar { name: ref n, hunger: 0...49 } => format!("Hi, {}", n),
Caterpillar { name: _, hunger: _ } => String::from("Impossibly hungry!"),
};
Match Expressions
https://play.rust-lang.org/?gist=42735afcf3785a0b6d84abe4963fc183&version=stable&mode=debug&edition=2015
| 25.10.2018 | Rust and Eclipse41
42. No traditional C-Style for-loops
For-in loops over types implementing IntoIterator trait
Examples:
for i in 1..=10 {
println!("{}", i)
}
for e in [1,2,3,5,8].iter() {
println!("{}", e)
}
For Loops
| 25.10.2018 | Rust and Eclipse42
https://play.rust-lang.org/?gist=f03ca224d5b2072615539a3ebdd1816f&version=stable&mode=debug&edition=2015
for (count,param) in std::env::args().enumerate() {
println!("Parameter {} is {}", count, param)
}
43. Loop continues until its condition evaluates to true
There is a while let variant(see 2nd Borrow Checker example), similar to if let
Example:
While Loops
| 25.10.2018 | Rust and Eclipse43
https://play.rust-lang.org/?gist=9814fa07fe79a0aa6b55044f1b173bab&version=stable&mode=debug&edition=2015
let mut curr = 1;
while curr < 100 {
println!("{}", curr);
curr *= 2;
}
44. May break with a value
Example:
Infinite Loops
| 25.10.2018 | Rust and Eclipse44
https://play.rust-lang.org/?gist=b2ea44f715a016af38ced22362fb8063&version=stable&mode=debug&edition=2015
use std::io::BufRead;
let stdin = std::io::stdin();
let user_input = loop {
let line = stdin.lock().lines().next();
if let Some(Ok(in_str)) = line {
break in_str;
}
};
45. The ? operator works differently than known from other languages
It is not the usual null-safe navigation
Extracts value from Option or Result; returns from function if used on None / Err
Example:
? Operator
| 25.10.2018 | Rust and Eclipse45
https://play.rust-lang.org/?gist=1bdd1afce12339140f6cf4a04c1b6680&version=stable&mode=debug&edition=2015
is transformed to
use std::str::from_utf8;
let bytes : &[u8] = &[0x0020, 0x0034, 0x0032];
let parsed : Result<&str, Utf8Error> = from_utf8(bytes);
let s = parsed?.trim(); let s = match parsed {
Ok(inner) => inner.trim(),
Err(e) => return Err(e.into()),
};
47. Rust is no “classical” object oriented language
There is no inheritance between data types
Traits provide a way to define interfaces (with re-usable functionality)
General Categorization
| 25.10.2018 | Rust and Eclipse47
48. Impl blocks for a data type can be defined in same module as the data type
They hold functions that can be called on the type or values of the type
Behavior for Data Types
| 25.10.2018 | Rust and Eclipse48
49. struct Caterpillar {
name : String,
hunger : u8
}
struct Butterfly {
name : String
}
Data Type Behavior Example : Data Structures
| 25.10.2018 | Rust and Eclipse49
https://play.rust-lang.org/?gist=fdae8cf00e4d52ff319c736c1bbd5b9e&version=stable&mode=debug&edition=2015
50. impl Caterpillar {
fn new(the_name : &str) -> Caterpillar {
Caterpillar {
name : String::from(the_name),
hunger : 100
}
}
fn eat(&mut self, amount : u8) {
self.hunger =
self.hunger.saturating_sub(amount);
}
fn transform(self) -> Butterfly {
Butterfly {
name : self.name
}
}
} // end impl Caterpillar
Data Type Behavior Example : Behavior
| 25.10.2018 | Rust and Eclipse50
https://play.rust-lang.org/?gist=fdae8cf00e4d52ff319c736c1bbd5b9e&version=stable&mode=debug&edition=2015
51. fn life_of_caterpillar_harry() {
let mut caterpillar = Caterpillar::new("Harry");
eat_some(&caterpillar);
let butterfly = caterpillar.transform();
caterpillar.eat(10);
}
fn eat_some(c : &Caterpillar) {
c.eat(50);
}
Data Type Behavior Example : Usage
| 25.10.2018 | Rust and Eclipse51
https://play.rust-lang.org/?gist=fdae8cf00e4d52ff319c736c1bbd5b9e&version=stable&mode=debug&edition=2015
Ownership already transferred
No mutable access
52. Are similar to interfaces of other languages; more similar to type classes in Haskell
Abstract a public API that can be implemented for types
Defines functions that must be implemented, or provide default implementations
May require other traits to also be implemented (similar to inheritance)
Can be implemented for types, if trait or type is located in same crate as implementation
Generics can define trait bounds, meaning a concrete type must have a trait implementation
Traits can be used as dyn reference (&dyn Trait); methods will be called via v-table
(dynamic dispatch)
Traits
| 25.10.2018 | Rust and Eclipse52
53. trait Emotions {
fn is_angry(&self) -> bool;
}
impl Emotions for Caterpillar {
fn is_angry(&self) -> bool {
self.hunger > 50
}
}
Trait Example
| 25.10.2018 | Rust and Eclipse53
https://play.rust-lang.org/?gist=9100b60676a020a24d788fc6a7c64904&version=stable&mode=debug&edition=2015
fn hangry_caterpillar() {
let c = Caterpillar::new("Harry");
if c.is_angry() {
println!("Leave him alone!");
}
}
54. // Silly example; see std::ops::Mul
trait Moar : Sized {
fn times(&self, usize) -> Self;
fn double(&self) -> Self {
self.times(2)
}
}
impl Moar for u32 {
fn times(&self, nr : usize) -> u32 {
self * (nr as u32)
}
}
Trait Example 2 : Default Implementations and Generic Use Over Trait
| 25.10.2018 | Rust and Eclipse54
https://play.rust-lang.org/?gist=cccab33989d4aa338e84a277c1af8add&version=stable&mode=debug&edition=2015
use std::fmt::Display;
fn print_double<T>(t : &T)
where T : Moar + Display {
println!("{}", t.double());
}
fn answer_to_question_of_life() {
print_double(&21);
}
55. trait Valueable : Display {
fn value(&self) -> usize;
}
impl Valueable for String {
fn value(&self) -> usize {
self.len()
}
}
fn print_value(item : &dyn Valueable) {
// item.value() dispatched via v-table
println!("{} has value {}", item, item.value())
}
Trait Example 3 : Dynamic Dispatch
| 25.10.2018 | Rust and Eclipse55
https://play.rust-lang.org/?gist=c34744420f4db7e72571f5264ae5887e&version=stable&mode=debug&edition=2015
57. LSP implementation that can be installed via rustup
Can be used as IDE / Editor backend providing “smarts”
Still in preview status
Seems to be unstable sometimes
Code completion sometimes incomplete (racer trades speed for accuracy)
Rust compiler needs some refactoring to be better designed for “pulling” info
The Rust Language Server — RLS
https://ncameron.org/blog/rls-1-0-release-candidate/
| 25.10.2018 | Rust and Eclipse57
58. Official Eclipse Foundation project for Rust support in the Eclipse IDE
Stands on the shoulders of giants
Eclipse CDT for debugging with GDB
Eclipse TM4E for syntax coloring and more
Eclipse LSP4E / LSP4J for editor support using RLS
https://www.eclipse.org/downloads/packages/release/2018-09/r/eclipse-ide-rust-developers-includes-incubating-components
Eclipse Corrosion
| 25.10.2018 | Rust and Eclipse58
LSP4J
RLS
TM4E
Corrosion
LSP4E CDT
59. Eclipse Corrosion : Current Features
| 25.10.2018 | Rust and Eclipse59
Compile Error Markers
Code Completion
Syntax Coloring
Outline
View
Find
References
60. • New project wizard (invoking cargo)
• Quick outline (Ctrl + O)
• Some quickfixes
(e.g. use suggestions for types not imported)
• Rename refactoring
Eclipse Corrosion: Some More Current Features
| 25.10.2018 | Rust and Eclipse60
• Compile/run via run configuration
• Debug rust programs (GDB only)
• Code formatting via RLS / rustfmt
• Navigate to definition
• Find implementations of traits / types
61. • Open symbol in workspace (Ctrl + Shift + T)
• Hover info
• Toggle comment
• Code folding (upcoming)
• Bracket matching and completion
• Code actions, e.g. continue started doc-comments (upcoming)
Eclipse Corrosion: Even More Current Features
| 25.10.2018 | Rust and Eclipse61
62. • Flat outline (RLS limitation)
• No unit test UI (mostly Rust limitation)
• Cannot show all trait implementations for type (LSP / RLS limitation)
• Very little refactoring capabilities (RLS limitation)
• No way to show all crate dependencies (LSP / RLS limitation)
Eclipse Corrosion: Some Current Limitations
| 25.10.2018 | Rust and Eclipse62
63. • No preview macro expansion in the editor (RLS limitation?)
• Hover info does not show specialized generic declarations (RLS limitation)
• Limited cargo support (e.g. cannot start benchmarks, doc generation etc.)
(Corrosion limitation)
• However, using an “External Tool” run configuration, specifying the command is possible
Eclipse Corrosion: More Current Limitations
| 25.10.2018 | Rust and Eclipse63
64. If you are used to Eclipse, Corrosion makes you feel right at home
Stability of the RLS & Corrosion combo got much better over the year
The overall package is still not what to expect from a full fledged IDE
Every now and then the language server stops working
Restart of Eclipse needed
Due to the stack it is not always clear which part is responsible for a problem
Where should a bug be reported?
Eclipse Corrosion, Experience Report
| 25.10.2018 | Rust and Eclipse64
66. Rust is a friendly systems programming language
Comes with build tool / package manager
→ Easy integration of external libraries / central lib repository
Fewer sharp edges (and errors at runtime) compared to C/C++
Guides to performant code
Eclipse Corrosion provides basic language support thanks to RLS
Rust and Eclipse have great and helpful communities
Conclusion
| 25.10.2018 | Rust and Eclipse66
68. Into Rust (short intro videos)
http://intorust.com/
Learning Rust (quick introduction)
https://learning-rust.github.io/
The Rust Programming Language Book
https://doc.rust-lang.org/book/
Rust by Example
https://doc.rust-lang.org/rust-by-example/
The new Rustacean Podcast
https://newrustacean.com/
Rust-Learning (list of further resources)
https://github.com/ctjhoa/rust-learning
Entry Points for Learning Rust
| 25.10.2018 | Rust and Eclipse68
69. Fraunhofer FOKUS
Institute for Open Communication Systems
Kaiserin-Augusta-Allee 31
10589 Berlin, Germany
info@fokus.fraunhofer.de
www.fokus.fraunhofer.de
Max Bureck
Thank You for Your Attention