summaryrefslogtreecommitdiff
path: root/meap/meap-code/ch3/ch3-implementing-display.rs
blob: 8537bd98282de3e30be6cbcf61ccf3b6d4e9658c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#![allow(dead_code)] // <1> Silence warnings related to FileState::Open not being used

use std::fmt;  // <2> Bring the `std::fmt` crate into local scope, allowing us to make use of `fmt::Result`
use std::fmt::{Display};  // <3> Bring `Display` into local scope, avoiding the need for us to prefix it as `fmt::Display` in our code

#[derive(Debug,PartialEq)]
enum FileState {
  Open,
  Closed,
}

#[derive(Debug)]
struct File {
  name: String,
  data: Vec<u8>,
  state: FileState,
}

impl Display for FileState {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     match *self {
         FileState::Open => write!(f, "OPEN"),     // <4> Sneakily, we can make use of `write!` to do the grunt work for us. Strings already implement `Display` themselves, so there's very little left for us to do.
         FileState::Closed => write!(f, "CLOSED"), // <4>
     }
   }
}

impl Display for File {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
      write!(f, "<{} ({})>", self.name, self.state)  // <5> We can rely on the FileState Display implementation in our own code 
   }
}

impl File {
  fn new(name: &str) -> File {
    File {
        name: String::from(name), 
        data: Vec::new(), 
        state: FileState::Closed
    }
  }
}

fn main() {
  let f5 = File::new("f5.txt");
  //...
  println!("{:?}", f5); // <1>
  println!("{}", f5); // <1>
}