Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Thomas Koehler
    @Bastacyclop
    Do you know the try!macro ?
    I think you could use it
    Alexander Chepurnoy
    @kushti
    @Bastacyclop update isn't returning a modified object. It's from "ring" framework. I tried try! but without success :)
    thanks, will read
    Thomas Koehler
    @Bastacyclop
    Don't you want to early return the Err's ?
    Alexander Chepurnoy
    @kushti
    @Bastacyclop it would be nice, how?
    Thomas Koehler
    @Bastacyclop
    fn file_digest(digest_alg: &'static digest::Algorithm, file_path: &std::path::Path) -> Result<Digest, std::string::String> {
        std::fs::File::open(file_path).map_err(|why| {
            format!("couldn't open {}: {}", file_path.display(), why.description())
        }).and_then(|mut file| {
            let mut ctx = digest::Context::new(digest_alg);
            let mut chunk = vec![0u8; 128 * 1024];
    
            loop {
                match file.read(&mut chunk[..]) {
                    Ok(0) => break,
                    Ok(bytes_read) => ctx.update(&chunk[0..bytes_read]),
                    Err(why) => {
                        return Err(format!("couldn't read {}: {}", file_path.display(), why.description()));
                    },
                }
            }
            Ok(x.finish())
        })
    }
    I'm not sure if you can use return inside the closure
    I think so
    It will probably return from the closure and not from the upper function but I guess it's fine
    Alexander Chepurnoy
    @kushti
    yes
    the only thing I dont' like is return in the middle
    Thomas Koehler
    @Bastacyclop
    well try! should help with that
    also you can early return after File::open
    Alexander Chepurnoy
    @kushti
    it is better to have a single expression in Rust also right?
    I'm coming from Scala :)
    Thomas Koehler
    @Bastacyclop
    well it is better when it is not worse :p
    usually with Result's you do it often
    since you abort what you are doing
    Alexander Chepurnoy
    @kushti
    ah okay
    and about mut, is it okay to have so much of them?
    Thomas Koehler
    @Bastacyclop
    well if you need to mutate things you do it
    Alexander Chepurnoy
    @kushti
    okay
    Thomas Koehler
    @Bastacyclop
    it might seem a bit verbose but it is a lot better to use than the const's of C(++)
    Alexander Chepurnoy
    @kushti
    it's not much verbose, but in Scala such an amount of mutables is a red flag. Rust is different. Where can I read "idiomatic" Rust code snippets?
    Thomas Koehler
    @Bastacyclop
    I think you can replace all you Err handling with try!, remember that try!uses Into/From automatically.
    because Scala is a lot more functionnal right ?
    Alexander Chepurnoy
    @kushti
    yes, exactly
    Thomas Koehler
    @Bastacyclop
    Rust is not
    Alexander Chepurnoy
    @kushti
    I see
    Thomas Koehler
    @Bastacyclop
    Well you have a lot of functionnal-like stuff
    but it is still a system language right
    about code snippets
    hmm
    the Book gives a good impression of course
    there is this ongoing thing: http://aturon.github.io/
    otherwise I don't really know I guess
    usually I just try to make things look right
    Alexander Chepurnoy
    @kushti
    thanks!
    Thomas Koehler
    @Bastacyclop
    fn file_digest(digest_alg: &'static digest::Algorithm, file_path: &std::path::Path) -> Result<Digest, std::string::String> {
        let mut file = try!(File::open(file_path).map_err(|why| format!("couldn't open {}: {}", file_path.display(), why.description()));
        let mut ctx = digest::Context::new(digest_alg);
        let mut chunk = vec![0u8; 128 * 1024];
    
        loop {
            let bytes_read = try!(file.read(&mut chunk[..]).map_err(|why| format!("couldn't read {}: {}", file_path.display(), why.description())));
            if bytes_read > 0 {
                ctx.update(&chunk[0..bytes_read]);
            } else {
                break;
            }
        }
    
        Ok(ctx.finish())
    }
    @kushti like this maybe ?
    don't forget you can shorten things like std::path::Path and std::io::File with use's
    also I don't think that returning a String error is very idiomatic
    Thomas Koehler
    @Bastacyclop

    Actually if what you want is a buffered reader:

    use std::path::Path;
    use std::io;
    
    // do you really need this lifetime to be 'static ??
    fn file_digest(digest_alg: &'static digest::Algorithm, file_path: &Path) -> io::Result<Digest> {
        let mut file = try!(io::File::open(file_path));
        let mut reader = BufReader::with_capacity(capacity, file);
        let mut ctx = digest::Context::new(digest_alg);
        for byte in reader.bytes() {
            ctx.update(try!(byte));
        }
        Ok(ctx.finish())
    }

    Also, your digest stuff could directly take an Iterator over bytes ?

    If you want you can still format your Strings from the Err afterwards
    Thomas Koehler
    @Bastacyclop
    my final version (hoping I have not completly diverged from what your code was about xD) would be something like:
    use std::path::Path;
    use std::io;
    
    fn file_digest(digest_alg: &digest::Algorithm, file_path: &Path) -> io::Result<Digest> {
        let mut file = try!(io::File::open(file_path));
        let mut reader = io::BufReader::with_capacity(capacity, file);
        try!(bytes_digest(digest_alg, reader.bytes()))
    }
    Alexander Chepurnoy
    @kushti
    @Bastacyclop impressive changes :) will try them, thanks!
    Benjamin Z
    @benjyz
    @kushti what does this code do? ;)
    Andréy Lesnikóv
    @ozkriff