These are chat archives for rust-lang/rust

17th
Dec 2017
Michael Thomas
@Michaelt293
Dec 17 2017 00:25

Regarding my previous question about downloading an image, I have written the following code -

extern crate reqwest;
extern crate image;

use std::io::Read;

fn main() {
    println!("Getting the image!");
    test()
}

fn test() {
    let mut req = reqwest::get("http://charts.bsch.com.au//tmp/gfs.stormcast.bsch.init-2017121512z.fcst-201712161600z.cape.nsw.null.0.png").expect("Failed to send request");
    let mut data = Vec::new();
    req.read_to_end(&mut data);
    println!("{:?}", &data);
    image::save_buffer("image.png", &data, 750, 563, image::RGB(8)).unwrap()
}

When running the program, I get the following error -

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("not enough image data provided") }) }', src/libcore/result.rs:906:4

Am I going about this the right way? (obviously no, ha!)

Pohl Longsine
@pohl
Dec 17 2017 04:44
You can avoid the unwrap() call by using an if let expression, and print any error that might come back. I ran your code and it reveals that not enough image data was provided to the call.
    if let Err(e)  = image::save_buffer("image.png", &data, 750, 563, image::RGB(8)) {
        println!("Error: {:?}", e);
    };
Michael Thomas
@Michaelt293
Dec 17 2017 05:09
Thanks, I'm not sure what image data I am missing though.
Alexey
@alleycat-at-git
Dec 17 2017 07:48

Hey guys! Can anyone help me out with noob question? I have the following code:

#[derive(Clone)]
enum Route {
    Root,
    User(String)
}

fn main() {
    c(Route::Root);
    println!("Hello, world!");
}

fn c(a: Route) {
    let closure = move || { 
        Some(a.clone())
    };
    let c = b(closure);
}

fn b<F: Fn() -> Option<Route> + 'static>(closure: F) {
}

Which works only if I have a.clone() call in fn c. When I remove that clone call - the compiler says that closure implements only FnOnce. I sort of understand why this is happening like you cannot move variable more than once and therefore isn't allowed to call function many times. But I do want to move that data only once (not cloning) into the closure and then be able to call it many times with that "cached" value. Is there a way to do it?

Denis Lisov
@tanriol
Dec 17 2017 08:14
Several. You can add a borrowed variant or use reference counting with Rc.
Restioson
@Restioson
Dec 17 2017 08:15
Is there any way to disable a dependency's dependency's feature?
Case: I'm trying to use array-init, but it depends on nodrop, which by default uses std. I am no-std, and nodrop has std in its default features, so how would i disable default features for array-init's nodrop?
Denis Lisov
@tanriol
Dec 17 2017 08:17
Does array-init have an std feature?
Restioson
@Restioson
Dec 17 2017 08:17
I believe array-init is no_std by default
@tanriol the feature it has is "nodrop/use_union"
but that's not related to std
Ok, it is always #![no_std]
Denis Lisov
@tanriol
Dec 17 2017 08:26
So array-init is no_std but unconditionally depends on nodrop[std]? I'd suggest you may want to make a PR fixing this, as this seems to be a problem making no_std on array-init worthless.
Restioson
@Restioson
Dec 17 2017 08:27
Hm, good idea
Denis Lisov
@tanriol
Dec 17 2017 08:27
...or maybe just use arrayvecinstead
Restioson
@Restioson
Dec 17 2017 08:28
I need to pass a nested mutable slice to something until const-generics gets impl'd
then i can use const generics
i could do it with unsafe, but...
I will look @ arrayvec though
Alexey
@alleycat-at-git
Dec 17 2017 08:30
Several. You can add a borrowed variant or use reference counting with Rc
@tanriol I tried to to it this way, but it says can't move out of borrowed content
#[derive(Clone)]
enum Route {
    Root,
    User(String)
}

fn main() {
    // let a = 1;
    // let closure = move || { println!("{}", a) };
    // let c = b(closure);
    c(Route::Root);
    println!("Hello, world!");
}

fn c(a: Route) {
    let rc = std::rc::Rc::new(a);
    let closure = move || { 
        Some(*rc)
    };
    let c = b(closure);
}

fn b<F: Fn() -> Option<Route> + 'static>(closure: F) {
}
And converting Fn() -> Option<Route> to Fn() -> Option<Rc<Route>> seems like an overkill for me. Is there is simpler way of doing it?
Restioson
@Restioson
Dec 17 2017 08:32
might have to clone
Restioson
@Restioson
Dec 17 2017 08:40
PR created. I might switch to ArrayVec though -- it depends if I can get this to work
Denis Lisov
@tanriol
Dec 17 2017 08:51
@alleycat-at-git You can have enum BorrowedRoute<'a> { Root, User(&'a str) } as a borrowed version, but to me this looks like an overkill.
this brings me pain
this is not good
wait phew i can kill the lifetime 'w
wait phew i can kill most of it
wait no i can't
dammit
Restioson
@Restioson
Dec 17 2017 08:59
well, at least now i only have 'w, A, E, T
Michael Thomas
@Michaelt293
Dec 17 2017 09:20

Using pngcheck, I get the following -

$ pngcheck gfs.stormcast.bsch.init-2017121512z.fcst-201712161600z.cape.nsw.null.0.png
OK: gfs.stormcast.bsch.init-2017121512z.fcst-201712161600z.cape.nsw.null.0.png (750x563, 24-bit RGB, non-interlaced, 94.9%).

I assume the issue is with the following line -

image::save_buffer("image.png", &data, 750, 563, image::RGB(8)).unwrap()

The dimensions are right and therefore I suspect the issue is with the ColorType but even with image::RGB(24), I still get an error.

Restioson
@Restioson
Dec 17 2017 09:36
@Michaelt293 can you open it in a viewer?
Michael Thomas
@Michaelt293
Dec 17 2017 09:37
Yep, opens just fine in Preview ..... I assume I am just doing something silly
Restioson
@Restioson
Dec 17 2017 09:38
Sorry, i'm not familiar with your issue -- what is the issue here?
ah found it, sorry
Are you sure that you get all the data?
Doesn't read_to_end return a result?
Michael Thomas
@Michaelt293
Dec 17 2017 09:42
No, I'm not sure I get all the data. read_to_end does return a result. In fact, I am getting a warning about that
warning: unused `std::result::Result` which must be used
Restioson
@Restioson
Dec 17 2017 09:42
One should always listen to rust ;P
in all seriousness, try expecting on that
The error may be related to that
Michael Thomas
@Michaelt293
Dec 17 2017 09:52
Thanks...... still get the same error though.
Michal 'vorner' Vaner
@vorner
Dec 17 2017 10:02
Hello. I'm doing some FFI with C++. What is the current state-of-the art representation of an opaque pointer? I get a lot of conflicting answers when searching the internet.
Restioson
@Restioson
Dec 17 2017 10:02
There's a section on that in the FFI section of TRPL I think
C++? Using C wrapper?
Also try *mut c_void
Michal 'vorner' Vaner
@vorner
Dec 17 2017 10:03
Yes, using a C wrapper.
Restioson
@Restioson
Dec 17 2017 10:03
Ah, ok
NicolasVidal
@NicolasVidal
Dec 17 2017 10:04
Hello there, did anyone tried its luck with tensorflow c_api from rust? :)
Restioson
@Restioson
Dec 17 2017 10:04
There are rust bindings
Limited tho afaik
Michal 'vorner' Vaner
@vorner
Dec 17 2017 10:05
I'm using pub enum Stuff {} for the thing that lives in C++ and I get only a pointer in Rust. This seems fine. But I want to do the opposite, pass a pointer to some (non-repr(C)) thing to C++ that'll be opaque to it. And I get a warning about that.
NicolasVidal
@NicolasVidal
Dec 17 2017 10:05
@Restioson that's why I'm using directly the c_api with bindgen and the 1.4 so/dll, I can load a model, feed it with some tensors, run a session, but I fail to correctly get the outputs :)
Restioson
@Restioson
Dec 17 2017 10:05
Sorry, i havent use either
Maciej Gorywoda
@makingthematrix
Dec 17 2017 10:09

Hi guys. A newbie here, coming from the Scala world :) I'm doing an exercise with operations on sets, and I'm ears deep into documentation right now, but I have a quick question. I operate on two HashSet<usize>s. When I substract one from the other like this:

let mut free_cities: HashSet<&usize> = all_cities.difference(&slave_cities).collect();

I get HashSet<&usize>. But what I want is another HashSet<usize>, so I can use it in next operations with the above two. Should I map it? Or is there a way to get HashSet<usize> directly?

Maciej Gorywoda
@makingthematrix
Dec 17 2017 10:28

ok, I got this:

let mut free_cities: HashSet<usize> = all_cities.difference(&used_cities).map(|&x| x).collect();

but maybe there is a better way?

Fra ns
@snarf95_twitter
Dec 17 2017 12:47
This should be the same
let mut free_cities: HashSet<_> = all_cities.difference(&used_cities).cloned().collect();
Bernhard Schuster
@drahnr
Dec 17 2017 14:10
Restioson
@Restioson
Dec 17 2017 15:27
Rust seems to not like stuff like Index<usize, Output=Whatever>
What's the correct way of writing this?
Wait no smh i'm dumb
Restioson
@Restioson
Dec 17 2017 15:38
Halp
Why isn't index<usize> impl for [T]
Denis Lisov
@tanriol
Dec 17 2017 15:41
It is implemented via the SliceIndex trait.
Restioson
@Restioson
Dec 17 2017 15:41
this makes it kinda impossible to use without const generics
Denis Lisov
@tanriol
Dec 17 2017 15:42
Why?
What exactly do you want to do?
Restioson
@Restioson
Dec 17 2017 15:42
You can't be generic over the size of your slice even with arrayvec if its nested more than once
i want to have an ArrayVec<[[T; N]; N2]>
so i made it ArrayVec<Array + Index<usize, Output=T> + IndexMut<usize> + SliceExt<Item=T> ... >
but it needs to be IndexMut<SliceIndex<*some slice type here*>>
I might give up and just use array-init and &mut [&mut [T]]
Restioson
@Restioson
Dec 17 2017 16:23
Yup, did that
https://i.imgur.com/Fs5ZuX8.png So... i got this error
There's an Ok(()) right there...
I'm sorta stumped
Ok wait, I left out a ; after an unsafe let binding
which gives me this error...
Restioson
@Restioson
Dec 17 2017 16:48
@Michaelt293 did you get it working? :smiley:
Pohl Longsine
@pohl
Dec 17 2017 19:33
@Michaelt293 Last night I wasn't able to understand why it doesn't think it has enough data, either. I'm on the edge of my seat, though, if you have an epiphany.
Restioson
@Restioson
Dec 17 2017 19:34
I reckon its the downloading
Denis Lisov
@tanriol
Dec 17 2017 19:46
@pohl Probably because the code did not make sense in the first place :-(
Pohl Longsine
@pohl
Dec 17 2017 19:49
Last night I ran it on my machine, and the download appears to populate the vec with all of the bytes.
Denis Lisov
@tanriol
Dec 17 2017 19:52
...with the png file. You don't need image to just save it.
extern crate reqwest;

use std::io::{Read, Write};
use std::fs::File;

fn main() {
    println!("Getting the image!");
    test()
}

const PATH: &'static str = "http://charts.bsch.com.au//tmp/gfs.stormcast.bsch.init-2017121512z.fcst-201712161600z.cape.nsw.null.0.png";

fn test() {
    let mut req = reqwest::get(PATH).expect("Failed to send request");
    let mut data = Vec::new();
    let mut out = File::create("image.png").expect("failed to create file");
    req.read_to_end(&mut data).expect("read failed");
    out.write(&data).expect("write failed");
}
Pohl Longsine
@pohl
Dec 17 2017 19:57
That makes sense now (the vec didn't contain the pixels, but instead contained the bytes that make up the PNG)
Jonas Platte
@jplatte
Dec 17 2017 19:59
Probably makes sense to use copy_to though instead of reading the whole thing into memory
Judson Lester
@nyarly
Dec 17 2017 20:28
This feels weird: I'm using the oauth2 crate. It's Config.set_redirect_url receives an Into<String>
I changed a hardcoded "string" into app_config.base_url - which resulted in a lifetime issue.
So I went from cfg.set_redirect_url(cfg.base_url) to cfg.set_redirect_url(&cfg.base_url) which gave me the trait bound 'std::string::String: std::convert::From<&std::string::String>' is not satisfied
But marking the arg as as &str works fine.
I guess I'm surprised that that's not an inference rustc will make.
I guess?
Michael Thomas
@Michaelt293
Dec 17 2017 20:44
@tanriol Awesome, that works. Thanks a lot.