-1

I am trying to have a struct which has a field which I assume should be of type Result<TempDir>. When I initialise an implementation of the field with new(), I would like that particular field to be initialised by the creation of a new temp directory. Later, I want to implement a method to read from that directory.

Here's the code, I am more worried about the syntax and proper use of libraries (why exactly are there over four libraries for read/write buffering in Rust, this is insane) as the logic should be right. Dont worry too much about the trait implementations, I just need directions in the syntax. Please don't be too harsh, as I know it doesn't compile, but with just two changes it should.

    extern crate rustc_back;
    use std::path::Path;
    use std::fs::File;
    use rustc_back::tempdir::TempDir as TempDir;
    pub struct MyStorage {

      temp_dir : Result<TempDir>
    }

    impl MyStorage {
      pub fn new() -> MyStorage { 
        //tempo = match TempDir::new("encrypt_storage");
        let store = match TempDir::new("encrypt_storage") {
          Ok(dir) => dir,
            Err(e) => panic!("couldn't create temporary directory: {}", e)
        };

        MyStorage { temp_dir: store }
        //MyStorage { temp_dir: TempDir::new("encrypt_storage") }
      }
    }

    impl Storage for MyStorage {
      fn get(&self, name: Vec<u8>) -> Vec<u8> {
    //let mut f = std::fs::File::open(self.temp_dir.path() / name);
    let mut f = std::fs::File::open(&self.temp_dir){
        // The `desc` field of `IoError` is a string that describes the error
        Err(why) => panic!("couldn't open: {}", why.description()),
        Ok(file) => file,
    };
    let mut s = String::new();
    //f.read_to_string(&mut s);
    match f.read_to_string(&mut s){
        Err(why) => panic!("couldn't read: {}", why.description()),
        Ok(_) => print!("contains:\n{}", s),
    }
    s.to_vec()
  }

  fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
    // self.entries.push(Entry { name : name, data : data })
    let mut f = File::create(self.temp_dir.path() / name);
    f.write_all(data);
  }

      fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
        // self.entries.push(Entry { name : name, data : data })
        let mut f = File::create(self.temp_dir.path() / name);
        f.write_all(data);
      }
    }
Lexka
  • 359
  • 1
  • 3
  • 9
  • 2
    What's the question? (e.g. what output do you get?) – huon Mar 18 '15 at 11:49
  • 2
    Welcome to Stack Overflow! To help you get better answers, please take the time to [produce better questions](http://stackoverflow.com/help/how-to-ask). Also review how to create a [MCVE](http://stackoverflow.com/help/mcve), which in this case means that you should create an example that reproduces the specific compiler error you are seeing. You should also **include** that error message in your question, to be sure other people see the same thing. – Shepmaster Mar 18 '15 at 13:26

1 Answers1

1

After fixing the indentation (Rust uses 4 spaces per level), removing the Storage for since you didn't provide that trait, removing commented-out code, and adding a main, you are left with this:

extern crate rustc_back;
use std::path::Path;
use std::fs::File;
use rustc_back::tempdir::TempDir as TempDir;

pub struct MyStorage {
    temp_dir : Result<TempDir>
}

impl MyStorage {
    pub fn new() -> MyStorage { 
        let store = match TempDir::new("encrypt_storage") {
            Ok(dir) => dir,
            Err(e) => panic!("couldn't create temporary directory: {}", e)
        };

        MyStorage { temp_dir: store }
    }
}

impl MyStorage {
    fn get(&self, name: Vec<u8>) -> Vec<u8> {
        let mut f = std::fs::File::open(self.temp_dir.path() / name);
        let mut s = String::new();
        f.read_to_string(&mut s);
        s.to_vec()
     }

    fn put(&mut self, name: Vec<u8>, data: Vec<u8>) {
        let mut f = File::create(self.temp_dir.path() / name);
        f.write_all(data);
    }
}

fn main() {}

Compiling that has this error:

error: wrong number of type arguments: expected 2, found 1 [E0243]
temp_dir : Result<TempDir>
           ^~~~~~~~~~~~~~~

Which nicely points to the problematic type. Let's look at the docs for Result, which includes the definition:

pub enum Result<T, E> {
    Ok(T),
    Err(E),
} 

So Result has two type parameters - T is used for the success case, and E is used for the failure case. Your code is only specifying one of them. My guess is that you looked at the docs for TempDir and copy-and-pasted:

fn new(prefix: &str) -> Result<TempDir>

However, if you click on the Result there, you'll see it goes to io::Result, which is simply a type alias that binds E to io::Error:

type Result<T> = Result<T, Error>; 

With all that exposition out of the way, you can "fix" your problem by changing your MyStorage struct:

pub struct MyStorage {
    temp_dir: std::io::Result<TempDir>,
}

And then you will get another compiler error, as you are already dealing with the Result via the match in MyStorage::new. You aren't storing a io::Result<TempDir>, you are just storing a TempDir! Changing your struct further:

pub struct MyStorage {
    temp_dir: TempDir,
}

unlocks a whole new set of errors for you to figure out; but now you have gotten past that first hurdle!

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Hi @shepmaster, can you help me out with this one, I am trying to open a file path and then transform the path into a vector, that's the get function up there, can you help? – Lexka Mar 18 '15 at 13:36
  • @Lexka oops, I forgot to add how to actually get rid of that single error. I've updated with that, but you are going to have a lot more errors to address! ^_^ Have fun! – Shepmaster Mar 18 '15 at 14:01
  • HI@sepmaster I had already figured the type was TempDir way before you replied, I just didnt want to say if I am honest, as I wanted to get more input. But I am a bit annoyed. I am trying to simply read in a path (get method) and then turn the path read in into a vector, but that doesn't seem to work, it's frustrating – Lexka Mar 18 '15 at 14:08
  • @Lexka Perhaps try simplifying your problem — remove code that isn't relevant to your problem, then either you will understand the issue or have another specific question you can search for or ask on SO. Posting code with a compilation error and then saying *"I had already figured [the error], I just didnt want to say"* is not a very friendly way to interact with people who are trying to help you! If you figured out the error, that's great! You can post it yourself and help others who come along after you. – Shepmaster Mar 18 '15 at 19:14
  • @Lexka As an aside, you don't have to at-mention the poster of thing you are commenting on - they are automatically notified. That's why the autocomplete doesn't work (and thus why you misspelled my username ^_^). – Shepmaster Mar 18 '15 at 19:15