Skip to content

Commit

Permalink
Separate Files
Browse files Browse the repository at this point in the history
  • Loading branch information
pflenker committed Apr 1, 2024
1 parent 23f1c0f commit 0208201
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 20 deletions.
32 changes: 32 additions & 0 deletions src/editor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::io::{self, Read};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

The two uses are copied from the main.rs.


pub struct Editor {

}

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

We define here a new, empty struct, and it's public.
public means that we can access it from elsewhere - i.e. the main.rs. This means we have a way to separate purely internal helper stuff from stuff we want others to know about. Neat!

The struct by itself is a bit meaningless up until here. We simply say "A construct exists, and this construct is called Editor", but nothing else. Yet.


impl Editor {

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

This starts the implementation block for this struct. Here, we can define different kinds of functions for structs. We'll define two different ones below.

pub fn default() -> Self {

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

This signature tells us a few things about the function.

  1. pub tells us it's public (see above)
  2. fn indicates it's a function.
  3. default is the name of this function. It's commonly used to create whatever we, the implementors, consider a default version of the Editor.
  4. () does not only indicate that this function takes no arguments, it also indicates that it can be called "standalone" (static in other programming languages) and doesn't need to be called on a specific instance of this struct. In Rust, this is called an associated function.
  5. -> Self tells us that this function returns an instance of Self, i.e. the kind of struct this is implemented on, i.e. Editor.
Editor{}

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

It's easy to miss, but this line returns something . Rust works like this: The last line of a block is returned if it doesn't end with a ;.
The last (and only) line here is Editor{}, which creates a new instance of our new struct, which is as empty as it can be (since we didn't add anything yet).

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

Try adding a ; here and see what happens.

}
pub fn run(&self){

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

The crucial difference to the function above is that here, we have the parameter &self. self is referencing the struct from the context, Editor, here. & means that we do not need to pass a whole struct, just a reference to it.
If you know other programming languages, this is an unfamiliar way of defining class functions , so a function that operates on a specific instance of Editor. We'll see how this plays out in action in a second.

By the way: we could also skip the whole shenanigans here, delete default and just make run an associated function like default above. This would work right now. We do it like this so that I can show you the difference between these two types of functions ahead of time and not as part of an even bigger commit later on.

enable_raw_mode().unwrap();
for b in io::stdin().bytes() {
match b {
Ok(b) => {
let c = b as char;
if c.is_control() {
println!("Binary: {0:08b} ASCII: {0:#03} \r", b);
} else {
println!("Binary: {0:08b} ASCII: {0:#03} Character: {1:#?}\r", b, c);
}
if c == 'q' {
break;
}
}
Err(err) => println!("Error: {}", err),
}
}
disable_raw_mode().unwrap();
}
}

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

Everything else above is copy-pasted from the old main.rs.

24 changes: 4 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
use std::io::{self, Read};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
mod editor;

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 3, 2024

Author Owner

This is how we make our new module - editor - known to the current module. It looks for a file called editor.rs or one called editor/mod.rs.

We start with the first for now, and will switch to the second later.

use editor::Editor;

fn main() {
enable_raw_mode().unwrap();
for b in io::stdin().bytes() {
match b {
Ok(b) => {
let c = b as char;
if c.is_control() {
println!("Binary: {0:08b} ASCII: {0:#03} \r", b);
} else {
println!("Binary: {0:08b} ASCII: {0:#03} Character: {1:#?}\r", b, c);
}
if c == 'q' {
break;
}
}
Err(err) => println!("Error: {}", err),
}
}
disable_raw_mode().unwrap();
let editor = Editor::default();

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

This is how we now use the static function to get a new Editor.

editor.run();

This comment has been minimized.

Copy link
@pflenker

pflenker Apr 1, 2024

Author Owner

And this is how we call a method on it.
But wait, shouldn't we pass a reference to an Editor to it, according to how we have defined this function above?
Nope, when called on a specific struct, Rust does this under the hood.
If you want to, you can call run the same as default and explicitly pass the new struct, by changing this line to:

 Editor::run(&editor); 
}

0 comments on commit 0208201

Please sign in to comment.