These are chat archives for rust-lang/rust

22nd
Sep 2018
Ichoran
@Ichoran
Sep 22 2018 00:01 UTC
@yurique - Congrats! (Also--let me know if you want some Scala performance tips. The difference shouldn't be that big if you're trying to make the Scala fast, but it is if you're doing a lot of stuff generically.)
:sparkles: for Rust's ability to deliver fast code without undue effort, though!
Sam A. Horvath-Hunt
@SamHH
Sep 22 2018 10:37 UTC

I have a map enum enum MapResult<T, U> { BTree(BTreeMap<T, U>), Hash(HashMap<T, U>) } (thanks to Thiez!). I'm requiring Map<String, String> as the argument in my method, that all works. what I'm wondering is if there's any way to access the map in a DRY way?

at the moment I'm repeating myself in each match:

for (index, (key, val)) in map.iter().enumerate() {
    println!("[{}]: {} ({})", index, key, val);
}

is there no way to use this one code block regardless of the type of map? given that the implementation is identical for both hashmap and btreemap

a more terse example:

let num_items = match map_btree_or_hash {
    Map::BTree(map) => map.len(),
    Map::Hash(map) => map.len(),
};

ideally I'd be able to just do map_btree_or_hash.len() since they both implement an identical method here in terms of signature

David Vo
@auscompgeek
Sep 22 2018 10:50 UTC
the only thing I can think of is maybe writing your own trait and providing implementations of it for BTreeMap and HashMap, but that would add a layer of indirection which you may or may not want
Sam A. Horvath-Hunt
@SamHH
Sep 22 2018 11:09 UTC
I tried that before but I was getting errors along the lines of Rust not knowing the size of sth at compile time. hmm
Denis Lisov
@tanriol
Sep 22 2018 11:14 UTC
If you already have an enum, you can write an impl for that enum that delegates to one or the other.
By the way, what's the reason you need to return either HashMap or BTreeMap?
Ash
@ashthespy
Sep 22 2018 11:27 UTC
Question about threads in rust - I spawned a thread that runs a udpsocket, listening with set_nonblocking(true) in a loop. I notice that this thread now quickly takes up 100% of the cpu. Would there be some resources I could go through to figure out why this is happening?
CorvusEtiam
@CorvusEtiam
Sep 22 2018 11:30 UTC
Is wrapping my database model into something akin to Java DAO is good idea under Rust? Or there are better/more idiomatic way?
Denis Lisov
@tanriol
Sep 22 2018 11:46 UTC
I'd probably not. IIUC, DAO means your objects access some hidden database connection, which is probably not a good idea :-)
Have you seen diesel?
Ash
@ashthespy
Sep 22 2018 12:29 UTC
added a 100 milli thread::sleep() and now it's all good.
But - what is the 'right' way go about something like this?
Denis Lisov
@tanriol
Sep 22 2018 12:30 UTC
@ashthespy The "right" way here is to use an asynchronous runtime like tokio
Or, if you don't need async, just remove set_nonblocking(true) and use a blocking socket :-)
Ash
@ashthespy
Sep 22 2018 12:31 UTC
to clarify - the main event loop uses tokio already
But I was having issues with wanting to run some async along with some blocking code via the main event loop.
After trying a few attempts, I gave up and just spawned a thread. :worried:
Denis Lisov
@tanriol
Sep 22 2018 12:34 UTC
Normally in such cases blocking code, if unavoidable, is offloaded to helper threads...
Ash
@ashthespy
Sep 22 2018 12:34 UTC
ah - I should read more - there is a tokio::spawn
PS - the main event loop here is librespot
Denis Lisov
@tanriol
Sep 22 2018 12:36 UTC
What kind of blocking code do you need to run?
Ash
@ashthespy
Sep 22 2018 12:37 UTC
gimme a second!
Ash
@ashthespy
Sep 22 2018 12:45 UTC
right, so the main even loop uses futures for all the communication with the sever, and a separate thread for downloading, and one for playback
but I was having issues with a future::sync::mscp::channel - messages from the thread would only after finishing the sever communication's poll
Denis Lisov
@tanriol
Sep 22 2018 12:50 UTC
I don't exactly understand where are the channel endpoints... both in the tokio runtime?
Ash
@ashthespy
Sep 22 2018 12:51 UTC
yes - one in a Future, and one in a worker thread, and the receiver in the main event loop
Ash
@ashthespy
Sep 22 2018 12:56 UTC
But this is not a general enough question for here :-) I was looking more for examples/resources of how to work with both blocking and nonblocking code with tokio
Denis Lisov
@tanriol
Sep 22 2018 13:01 UTC
The tokio threadpool has a special blocking function for that. Basically that function means "I'm entering blocking code, please wakeup another thread for async processing"
A good example is tokio-fs as lots of filesystem operations do not support async, so it has to wrap them.
Ash
@ashthespy
Sep 22 2018 13:11 UTC
Thanks! Will get back to reading. FWIW - I took care the high cpu for the interim by switching my std::sync::mpsc::Receiver::try_recv() calls to recv_timeout() to block for a while.
But I must say - coming from more the scientific computing world, I am having a load of fun with Rust! :-)
Sam A. Horvath-Hunt
@SamHH
Sep 22 2018 13:22 UTC

sorry I went afk while you were helping me @tanriol ! basically I have a series of structs representing lists of data, and how that data is stored depends on the specific implementation.. basically HashMapby default, but in some cases I use BTreeMap because occasionally ordering matters

probably premature optimisation, but I'm more curious than anything as I'm just doing this project to get to know Rust better

I'm aware it'd probably just be simpler to always use BTreeMap :tongue:
Denis Lisov
@tanriol
Sep 22 2018 13:41 UTC
That would be one option :-) also you could use an associated type to mark types as "hashed" or "ordered"...
Sam A. Horvath-Hunt
@SamHH
Sep 22 2018 13:51 UTC
ah, I haven't reached that part of the Rust book yet, might jump ahead a bit... :-) cheers
Farzeen
@happycoder97
Sep 22 2018 17:35 UTC
#![allow(unused_variables)]

trait FooTrait {}
struct FooStruct;
impl FooTrait for FooStruct {}

fn foo(f: &FooTrait) {}

fn main() {
    let a = FooStruct;
    let b = Box::new(a);
    let l = foo(&b);  // doesn't work
    let l = foo(&b as &FooStruct); // works
}
Shouldn't &b get coerced to &FooStruct?
Zakarum
@omni-viral
Sep 22 2018 18:02 UTC
Try foo(&*b)
Farzeen
@happycoder97
Sep 22 2018 18:02 UTC
But why is that necessary?
Why simple &b doesn't work?
Zakarum
@omni-viral
Sep 22 2018 18:03 UTC
I think because expression requires two coercions
Farzeen
@happycoder97
Sep 22 2018 18:03 UTC
Oh..
May be that's why
Thanks @omni-viral :+1:
Zakarum
@omni-viral
Sep 22 2018 18:04 UTC
&Box<T> to &T and to trait
Farzeen
@happycoder97
Sep 22 2018 18:04 UTC
yes
Ash
@ashthespy
Sep 22 2018 20:37 UTC
is there a way to profile my rust application to determine what is inflating the binary size?
matrixbot
@matrixbot
Sep 22 2018 20:38 UTC
bspeice Cargo-bloat is a good place to start if you haven't already: https://github.com/RazrFalcon/cargo-bloat
bspeice Clap (the arguments parser) had a pretty interesting case study at the beginning of the year: https://clap.rs/2018/01/09/new-years-weight-loss/
Ash
@ashthespy
Sep 22 2018 20:41 UTC
:O are you really a bot? if so that is pretty spot on.
matrixbot
@matrixbot
Sep 22 2018 20:41 UTC
bspeice Nah, I just prefer using Matrix/Riot over the Gitter page. Easier to have only one thing open at a time.
bspeice Though I'll admit my friends might think I'm part robot :)
Ash
@ashthespy
Sep 22 2018 20:43 UTC
But thanks, looks exactly like what I need! :-)
i.e the links
I have a 105mb dev binary, and a 15mb release binary.
Ash
@ashthespy
Sep 22 2018 21:49 UTC
back to basics,
Is there a more idiomatic way to do this?
#[derive(Debug)]
enum Myfruits {
    Unknown,
    Apple,
    Orange,
    Banana,
}

fn test_fruit(fruit: &str) -> Myfruits {
    match fruit {
        "Apple" => Myfruits::Apple,
        "Orange" => Myfruits::Orange,
        "Banana" => Myfruits::Banana,
        _ => Myfruits::Unknown,
    }
}

fn main() {
    let input: &str = "Orange";
    let found_fruit = test_fruit(input);
    println!(" In {} => {:?} ", input, found_fruit);
}
Thiez
@Thiez
Sep 22 2018 21:50 UTC
Absolutely, implement FromStr instead :D
Ash
@ashthespy
Sep 22 2018 21:52 UTC
But I still have to the matching right?
Thiez
@Thiez
Sep 22 2018 21:53 UTC
Yes I think so. I don't think you can derive it, but I can't say that I've tried
Ash
@ashthespy
Sep 22 2018 21:55 UTC
To derive it isn't that hard:
impl Myfruits {
    fn to_string(&self) -> String {
        return format!("{:?}", self);
    }
}
Thiez
@Thiez
Sep 22 2018 21:56 UTC
Ah, putting the To into FromStr ;)
Ash
@ashthespy
Sep 22 2018 21:57 UTC
letting [derive(debug)] do all the hard work :P
Thiez
@Thiez
Sep 22 2018 21:57 UTC
I feel like we're having some great miscommunication going on here, but you seem to be happy so let's call it a win :D
Ash
@ashthespy
Sep 22 2018 21:57 UTC
Ideally I'd like to have input be matched directly against the enum's fieldsnames
Zakarum
@omni-viral
Sep 22 2018 21:58 UTC
@ashthespy It is more idiomatic to write just format!("{:?}", self) instead of return format!("{:?}", self);
Ash
@ashthespy
Sep 22 2018 21:58 UTC
fair point.
Zakarum
@omni-viral
Sep 22 2018 21:59 UTC
And IIRC there is ToString trait that is implemented for T: Display
So Myfruits seems to have to_string method defined already. No need to write your own
Ah. It only implements Debug. My bad. Eyes closing. Need go to rest.
Ash
@ashthespy
Sep 22 2018 22:02 UTC
I shall get back to the book :-)