These are chat archives for rust-lang/rust

3rd
May 2016
Jacob Moen
@jacmoe
May 03 2016 10:05
That introductory Rust tutorial is not cool @mhsjlw - it's okay, but there are some issues with it. The guy who made the tutorial seems to be more interested in quantity than quality - he just seem to pump out tutorials. Take it with lots of salt. :)
Zakarum
@omni-viral
May 03 2016 10:31
@achempion You want to do that without explicit enumeration of all columns?
If so than I fear it is impossible to do
mhsjlw
@mhsjlw
May 03 2016 10:38
@jacmoe Yeah, no, It's not meant as a 'Just go write rust you're 100% ready, just go do it' I take it more as a introduction to rust syntax and nothing more. If you want to learn rust, use the official rust docs and learnrustbyexample
also wtf who if(asd == asd) && (asd == asd)
why ?!?!??!
He does a really bad job at explaining what he's doing... you're right.
mhsjlw
@mhsjlw
May 03 2016 11:18
Hi, I'm using the bytesorder crate and I want to read bytes out of a TcpStream I have this function: let mut reader = BufReader<TcpStream>::new(self.data.clone()); to create a bufreader for the current stream then I try to read bytes out of it like this:
return PositionAndOrientation {
      player_id: reader.read_u8().unwrap(),
      x: reader.read_i16::<BigEndian>().unwrap(),
      y: reader.read_i16::<BigEndian>().unwrap(),
      z: reader.read_i16::<BigEndian>().unwrap(),
      yaw: reader.read_u8().unwrap(),
      pitch: reader.read_u8().unwrap()
    };
and I keep getting the error: src/packets.rs:75:22: 75:29 note: the methodread_u8exists but the following trait bounds were not satisfied:bool : std::io::Read``
same for the i16 too
note: the methodread_i16exists but the following trait bounds were not satisfied:bool : std::io::Read``
Daniel Collin
@emoon
May 03 2016 11:22
@mhsjlw maybe you need to do use std::io::Read;
I think the compiler should suggest it though if you read more of the output
Erik Hedvall
@Ogeon
May 03 2016 11:23
Looks like something in reader prevents it from implementing Read. TcpStream does implement Read without any conditions, so it's hard to say... Are there any other related error messages?
Daniel Collin
@emoon
May 03 2016 11:23
but I may be wrong also (likely!)
mhsjlw
@mhsjlw
May 03 2016 11:24
Yeah using read didn't do it

@Ogeon this may help:

BufReader is the name of a struct or struct variant, but this expression uses it like a function name [E0423]
src/packets.rs:74 let mut reader = BufReader<TcpStream>::new(&self.data.clone());

Right now I'm pretty much trying to imply TcpStream to add some functions for reading and sending packets for a game server, if that helps also
(it's my first big rust project!)
Erik Hedvall
@Ogeon
May 03 2016 11:27
Strange message... You shouldn't need the <TcpStream> part at all, but in case you do, I think it should be BufReader::<TcpStream>::new(&self.data.clone())
Notice the extra :: before <
Oh, and since you are using & it will end up being a BufReader<&TcpStream>
That could be it, actually
mhsjlw
@mhsjlw
May 03 2016 11:29
src/packets.rs:37:51: 37:69 error: mismatched types:
 expected `&std::net::tcp::TcpStream`,
    found `&collections::vec::Vec<u8>`
(expected struct `std::net::tcp::TcpStream`,
    found struct `collections::vec::Vec`) [E0308]
src/packets.rs:37     let mut reader = BufReader::<&TcpStream>::new(&self.data.clone());
                                                                    ^~~~~~~~~~~~~~~~~
that's strange
does that mean I don't need the &TcpStream ?
because when I was using just the BufReader I don't think it worked
src/packets.rs:37:22: 37:36 error: the trait `std::io::Read` is not implemented for the type `&collections::vec::Vec<u8>` [E0277]
src/packets.rs:37     let mut reader = BufReader::new(&self.data.clone());
                                       ^~~~~~~~~~~~~~
yeah no TcpStream seems to break it
Erik Hedvall
@Ogeon
May 03 2016 11:31
It basically says that self.data is a Vec<u8>
mhsjlw
@mhsjlw
May 03 2016 11:31
here is an example function then if it helps
pub fn parse_message(&self) -> Message {
    let mut reader = BufReader::new(&self.data.clone());
    return Message {
      unused: reader.read_u8().unwrap(),
      message: reader.read_mc_string()
    };
  }
I return a struct that has the decoded packet data
Erik Hedvall
@Ogeon
May 03 2016 11:33
I don't think self.data is a TcpStream at all
mhsjlw
@mhsjlw
May 03 2016 11:33
??
what could it be ?
Erik Hedvall
@Ogeon
May 03 2016 11:33
Vec<u8>
mhsjlw
@mhsjlw
May 03 2016 11:34
interesting
Zakarum
@omni-viral
May 03 2016 11:34
Because of this part of message &collections::vec::Vec<u8>
Erik Hedvall
@Ogeon
May 03 2016 11:34
That's what the errors are saying
mhsjlw
@mhsjlw
May 03 2016 11:34
but then I can't call read_u8 etc.
because it only works on readers
Erik Hedvall
@Ogeon
May 03 2016 11:34
Exactly
that's the library
so what should I do ?
Erik Hedvall
@Ogeon
May 03 2016 11:37
I can't remember if there's an easy way to read from Vec, but that's what you want to do, unless it's actually supposed to be a TcpStream
Zakarum
@omni-viral
May 03 2016 11:37
@mhsjlw look at std::io::Cursor
It is an easy way to read from anything that AsRef<[u8]>
mhsjlw
@mhsjlw
May 03 2016 11:38
Cursor::new(&self.data.clone()); ?
could that work ?
Erik Hedvall
@Ogeon
May 03 2016 11:38
:+1:
You don't need to clone in that case
mhsjlw
@mhsjlw
May 03 2016 11:39
awesome !
ok, no more errors for that, thanks!
I have this function
pub fn receive(mut conn: TcpStream) -> Packet {
    let packet_id = conn.read_u8().unwrap();

    let mut packet_len = match packet_id {
      0x00 => 130,
      0x05 => 8,
      0x08 => 9,
      0x0d => 65,
      _ => 0
    };

    conn.read_exact(packet_len).unwrap();

    return Packet {
      packet_id: packet_id,
      packet_len: packet_len,
      data: data
    };
  }
everytime I recieve a packet this will run
and I match the id to the packet length
and then try to capture the whole message with conn.read_exact
ah there is a mistake in that code that I forgot to include
let mut data = conn.read_exact(packet_len).unwrap();
src/packets.rs:27:36: 27:46 error: mismatched types:
 expected `&mut [u8]`,
    found `_`
(expected &-ptr,
    found integral variable) [E0308]
src/packets.rs:27     let mut data = conn.read_exact(packet_len).unwrap();
                                                     ^~~~~~~~~~
src/packets.rs:27:36: 27:46 help: run `rustc --explain E0308` to see a detailed explanation
src/packets.rs:32:13: 32:17 error: mismatched types:
 expected `collections::vec::Vec<u8>`,
    found `()`
(expected struct `collections::vec::Vec`,
    found ()) [E0308]
src/packets.rs:32       data: data
                              ^~~~
it is once again mismatched types
but I'm not sure what I'm doing wrong
Daniel Collin
@emoon
May 03 2016 11:44
I would suggest you do Result<Packet> here and not just unwrap but that is up to you of course, if the read can't fail then it wouldn't be needed.
mhsjlw
@mhsjlw
May 03 2016 11:44
yeah the read is very unlikely to fail, but it can
Erik Hedvall
@Ogeon
May 03 2016 11:46
Well, almost everything is in the messages. The trick is to understand them. The first error says that read_exact wants a mutable slice of bytes. That slice should be as long as the message you want to read. The second error says that data is of the type (), but it's expected to be Vec<u8>.
mhsjlw
@mhsjlw
May 03 2016 11:51
oh yeah
here is the struct by the way
pub struct Packet{
  pub packet_id: u8,
  pub packet_len: usize,
  pub data: Vec<u8>
}
Erik Hedvall
@Ogeon
May 03 2016 11:51
The documentation for read_exact says that the input is the buffer you want to fill with data, and there's a very nice example of how to use it.
Zakarum
@omni-viral
May 03 2016 11:51
@mhsjlw why have packet_len when you have Vec?
mhsjlw
@mhsjlw
May 03 2016 11:52
I just thought that was the way to do it @SCareAngel but I guess it isn't needed...
Erik Hedvall
@Ogeon
May 03 2016 11:52
Vec carries its length with it, and you can get it using data.len()
Zakarum
@omni-viral
May 03 2016 11:53

In this part

 return Packet {
      packet_id: packet_id,
      packet_len: packet_len,
      data: data
    };

data is actually undefined

Erik Hedvall
@Ogeon
May 03 2016 11:54
@SCareAngel the code block has a typo
mhsjlw
@mhsjlw
May 03 2016 11:54
yeah I said I made a mistake
ah there is a mistake in that code that I forgot to include
let mut data = conn.read_exact(packet_len).unwrap();
I thought read_exact took a size, then returned the data
Zakarum
@omni-viral
May 03 2016 11:54
pub fn receive(mut conn: TcpStream) -> Packet {
    let packet_id = conn.read_u8().unwrap();

    let mut packet_len = match packet_id {
      0x00 => 130,
      0x05 => 8,
      0x08 => 9,
      0x0d => 65,
      _ => 0
    };

    let mut data = Vec::new();
    data.resize(packet_len, 0);
    conn.read_exact(&mut data[..]).unwrap();

    return Packet {
      packet_id: packet_id,
      data: data
    };
  }
Something like this should work
mhsjlw
@mhsjlw
May 03 2016 11:55
Yeah that did it
Thank you
That was just reading >_< now I have to work on writing
Zakarum
@omni-viral
May 03 2016 11:56
Actually
pub fn receive(mut conn: TcpStream) -> ::std::io::Result<Packet> {
    let packet_id = conn.read_u8().unwrap();

    let mut packet_len = match packet_id {
      0x00 => 130,
      0x05 => 8,
      0x08 => 9,
      0x0d => 65,
      _ => 0
    };

    let mut data = Vec::new();
    data.resize(packet_len, 0);
    try!(conn.read_exact(&mut data[..]));

    Ok(Packet {
      packet_id: packet_id,
      data: data
    })
  }
mhsjlw
@mhsjlw
May 03 2016 11:57
ok thanks
error catching ?
Erik Hedvall
@Ogeon
May 03 2016 11:57
let mut data = vec![0; packet_len];
try!(conn.read_exact(&mut data));
The vec! macro is nice, and &mut Vec<T> is coerced to &mut [T].
Zakarum
@omni-viral
May 03 2016 11:57
Because unwrap makes small kittens cry
mhsjlw
@mhsjlw
May 03 2016 11:57
ha!
it makes me cry :P
Zakarum
@omni-viral
May 03 2016 11:58
@Ogeon I don't remember all coercion rules yet. So I wrote thing clearer
Erik Hedvall
@Ogeon
May 03 2016 11:58
It's ok, I forgot to write "or you could..." at the beginning.
Zakarum
@omni-viral
May 03 2016 11:59
)
Erik Hedvall
@Ogeon
May 03 2016 11:59
Both are valid
Zakarum
@omni-viral
May 03 2016 11:59
But I'm gonna remember that macro with sizing trick
Should be easy since defining array have same syntax
Erik Hedvall
@Ogeon
May 03 2016 12:01
Yeah, just think of it as a fancy array definition
Zakarum
@omni-viral
May 03 2016 12:02
@mhsjlw. You should remove mut in let mut packet_len
mhsjlw
@mhsjlw
May 03 2016 12:05
Ok, will do
hmm
I'm not having some issues with writing
and I just can't seem to figure out what the problem is
mhsjlw
@mhsjlw
May 03 2016 12:10
(I'm impl TcpSocket so I can just call sending packets easily)
for example I've got this
fn send_ping(&mut self) {
    self.write_u8::<BigEndian>(0x01).unwrap();
  }
where self is the socket
and I am trying to write to the socket with byteorder and it says that I can't do it because it's not a function
do I need to create a cursor then write to that then send that ?
because that just seems tedious and slow
oh actually
derp
self.write_u8(0x01).unwrap();
you can't have endian on a byte
that's not the problem though anyway
Erik Hedvall
@Ogeon
May 03 2016 12:12
You can't impl TcpSocket unless you impl MyTrait for TcpSocket...
You don't own TcpSocket
mhsjlw
@mhsjlw
May 03 2016 12:13
I create a trait containing the functions
then I impl Packets for TcpStream {
Erik Hedvall
@Ogeon
May 03 2016 12:13
Alright, good :)
mhsjlw
@mhsjlw
May 03 2016 12:13
then i define the functions
*I
Erik Hedvall
@Ogeon
May 03 2016 12:15
So, is it saying that send_ping is missing? Is Packets defined in the same module as where you are calling it?
If it's not there, then you will have to use path::to::Packets;
mhsjlw
@mhsjlw
May 03 2016 12:16
No that's not it
src/packets.rs:180:10: 180:18 error: no method named `write_u8` found for type `&mut std::net::tcp::TcpStream` in the current scope
src/packets.rs:180     self.write_u8(0x01).unwrap();
byteorder can't directly write to a TcpStream
so I'm asking how I should do it
mhsjlw
@mhsjlw
May 03 2016 12:22
would a cursor do the trick @Ogeon ? Like creating one, writing to it then trying to write the cursor to the stream ?
Erik Hedvall
@Ogeon
May 03 2016 12:22
The docs says that there is no write_u8 for TcpStream, so the error is understandable. Did you mean to use the one from WriteBytesExt? Have you added use byteorder::WriteBytesExt;?
mhsjlw
@mhsjlw
May 03 2016 12:22
Yeah
I'm useing it and that's how I'm trying to write
no method named `write` found for type `&mut std::net::tcp::TcpStream` in the current scope
src/packets.rs:143     self.write(data);
uhhh
no method named write found ?
Erik Hedvall
@Ogeon
May 03 2016 12:23
speaking to myself ...what's that even implemented for...?
You need std::io::Write for write
mhsjlw
@mhsjlw
May 03 2016 12:24
I have .write because I am sending binary data that comes from a file
Erik Hedvall
@Ogeon
May 03 2016 12:24
impl<W: io::Write + ?Sized> WriteBytesExt for W {} ...?
mhsjlw
@mhsjlw
May 03 2016 12:24
it contains map data
Erik Hedvall
@Ogeon
May 03 2016 12:24
It should work
Oh, wait...
mhsjlw
@mhsjlw
May 03 2016 12:26
?
Erik Hedvall
@Ogeon
May 03 2016 12:26
Never mind. It should work. I don't understand what's happening
mhsjlw
@mhsjlw
May 03 2016 12:27
It's strange, I agree
my uses
use std::net::TcpStream;
use byteorder::{BigEndian, ReadBytesExt};
use std::io::BufReader;
use std::io::Read;
use std::io::Cursor;
use std::io::Write;
Erik Hedvall
@Ogeon
May 03 2016 12:27
No WriteBytesExt?
mhsjlw
@mhsjlw
May 03 2016 12:27
I'm really sorry
Erik Hedvall
@Ogeon
May 03 2016 12:27
..or are you just trying with Read now?
mhsjlw
@mhsjlw
May 03 2016 12:28
that was stupid of me
I forgot....
Erik Hedvall
@Ogeon
May 03 2016 12:28
*Write
mhsjlw
@mhsjlw
May 03 2016 12:28
no I use'd it and now it works
rookie mistake
Erik Hedvall
@Ogeon
May 03 2016 12:28
Huh, allright
mhsjlw
@mhsjlw
May 03 2016 12:28
xD
thank you though
Erik Hedvall
@Ogeon
May 03 2016 12:29
I'm still not sure why self.write(data); failed if you have use std::io::Write;
mhsjlw
@mhsjlw
May 03 2016 12:30
No that's fixed
everything is working
thank you
Erik Hedvall
@Ogeon
May 03 2016 12:30
Ok, good :smile:
mhsjlw
@mhsjlw
May 03 2016 12:30
also thank you for putting up with my lack of knowledge :P
I'm really enjoying the rust language
I think now that the entire server is working... just for learning purposes it'd be interesting to write a plugin api...
A quick search on crates seems that lua has plenty of bindings
I'll explore that
Erik Hedvall
@Ogeon
May 03 2016 12:34

Oh, no problem at all. It just took a moment to realize how much I need to explain :smile: Nice to see that you like the language.

The lua crate is quite incomplete, last time I checked, so you may bump into a few roadblocks, but it depends on what you want to do. Still worth giving it a try.

mhsjlw
@mhsjlw
May 03 2016 15:53
last updated : 5 months ago
yeah hmm
Erik Hedvall
@Ogeon
May 03 2016 16:07
The accuracy of my experience has not been determined
mhsjlw
@mhsjlw
May 03 2016 16:12
I'd do like plugin loading system where you dump lua files in the plugins/ folder for example then it loads all of them and executes codes based on hooks
something like that
LeonineKing1199
@LeonineKing1199
May 03 2016 16:31
This all makes perfect sense now...
Anyway, what's some cool things people are doing in Rust? I know it's still kind of a baby language and I already checked on github but I'm still curious, what are some cool things that people are doing in Rust?
Erik Hedvall
@Ogeon
May 03 2016 16:34
@mhsjlw I don't know what it's capable of anymore, so I can't say. I had trouble calling Rust functions from lua, but that may have been implemented by now. I simply don't know.
Daniel Collin
@emoon
May 03 2016 16:44
@LeonineKing1199 Depends on what you consider cool. Rust is written in Rust otherwise I guess servo (from Mozilla) is the most known project.
LeonineKing1199
@LeonineKing1199
May 03 2016 16:44

Well, I'm a computational geometry buff. And I guess physics too.

I'm also huge into parallelization and have written triangulation software in CUDA as well.

I work as full-stack web developer.

So, I'm kind of interested in all things. I'm a huge C++ buff and I'm curious about Rust and if there's anything about it that'd make me consider using it.

Erik Hedvall
@Ogeon
May 03 2016 16:47
@mhsjlw I just realized that we are probably talking about different lua bindings. I was using hlua
...and I though you wrote "5 minutes ago" while walking by my computer :P
LeonineKing1199
@LeonineKing1199
May 03 2016 16:56

Like for one, does Rust support generics as well as C++11 does?

Like, I can do this:

template <typename ...Args>
void emplace_back(Args&& ...args)
{
   new(address) value_type{std::forward<Args>(args)...};
}

So that's basically construction an object in memory, forwarding a variable number of arguments. It's pretty standard now in the C++ world. Can I do this in Rust? Because there's plenty of times in other languages where I simply want to forward arugments around.

Erik Hedvall
@Ogeon
May 03 2016 17:00
Rust doesn't support variable number of arguments at all for non-FFI functions, to begin with, and it's not a full blown templating system, just type parameters. It's still static dispatch in about the same way as in C++, but it works more like Java generics.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:02

Is it mean to say that that's unfortunate? I know Rust is still relatively young so it gets slack but do you know if they have plans for variable numbers of arguments?

Edit: Or is Rust just not that kind of language?

Maybe I'm misinterpreting Rust's overall purpose as a tool...

Rust, what's the point of it? What're we trying to solve/fix in the realm of programming languages?

Erik Hedvall
@Ogeon
May 03 2016 17:05
If it's unfortunate or not depends on each and everyone's opinion. I can live without it, so I'm not bothered. I haven't seen any signs of it being an upcoming features (no accepted RFC, as far as I can remember)
LeonineKing1199
@LeonineKing1199
May 03 2016 17:06

Well, the gitter description describes Rust as safe, concurrent and practical...

Putting concurrent and practical in the same sentence almost feels like a lie...

Nothing concurrent has ever been practically managed. There's literally always a race condition you didn't code for with synchronization steps that would defeat the point of concurrency.

But I'm pessimistic about concurrent software lol
Daniel Collin
@emoon
May 03 2016 17:08
Have you looked at how Rust deals with this?
There can only be one writer to one pice of data, always.
Sean Perry
@shaleh
May 03 2016 17:08
Read some Rust code. Try and write a simple server. Say, re-implement redis.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:09
Ah, that's why Rust is attractive to me. There's hardly any good HTTP frameworks in C++. Rust seems like it better supports this. I'd love to move away from all JavaScript all the time.
And does Rust just implement spinlocks for writing or does it use a full-on OS-level mutex?
Daniel Collin
@emoon
May 03 2016 17:10
Rust does more than than, it prevents even (in some cases) data races at compile time
LeonineKing1199
@LeonineKing1199
May 03 2016 17:10
That's an impressive claim...
LeonineKing1199
@LeonineKing1199
May 03 2016 17:11
The compiler knows you're spawning threads and it knows each threads instruction stack... That must be some badass static analysis to parse the source and determine that a thread will be conflicting with another at a location in memory.
Erik Hedvall
@Ogeon
May 03 2016 17:11
Much of it is part of the type system (like unique write access, Send and Sync traits, etc.), but there are also the common concurrency primitives
Daniel Collin
@emoon
May 03 2016 17:11
indeed
@LeonineKing1199 as @Ogeon points out. This happens on a more fundemental level in Rust.
Erik Hedvall
@Ogeon
May 03 2016 17:12
It's actually very clever
Daniel Collin
@emoon
May 03 2016 17:12
Sure is
LeonineKing1199
@LeonineKing1199
May 03 2016 17:13
You can even share stack frames?
Wow. You can't do that in C++
Daniel Collin
@emoon
May 03 2016 17:13
you can if you want (with tricks) I wouldn’t recommend it though :)
LeonineKing1199
@LeonineKing1199
May 03 2016 17:14
It seems like you'd have to abuse move semantics into oblivion, which is what Rust seems to be doing.
That's interesting, you can guarantee thread safety by changing ownership of the data, ha! It's all so clever!!!
Daniel Collin
@emoon
May 03 2016 17:14
threading is data problem and not a code problem.
so it makes sense
LeonineKing1199
@LeonineKing1199
May 03 2016 17:15
Interesting, I'm going to have read more on this. Thank you for the interesting discussion about some of Rust's implementation details.
Erik Hedvall
@Ogeon
May 03 2016 17:16
Have fun :smile:
Daniel Collin
@emoon
May 03 2016 17:16
np! Lots of interesting things to learn :)
LeonineKing1199
@LeonineKing1199
May 03 2016 17:16
I think Rust has great potential but its biggest obstacle will be C++ programmers. I think if Rust really wants to gain foothold, it's going to have to 'attack' C++, showing "Hey, this is dumb in C++ but it's easy in Rust."
And then there's C off in its own corner but no one cares about that except for embedded devs
Sean Perry
@shaleh
May 03 2016 17:17
nah. C++ dinosaurs know they like it or they go hang out in tar pits.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:17
:plus1:
C++11 and onwards though is a pretty tough contender
Sean Perry
@shaleh
May 03 2016 17:18
once the language stabilizes I think people will be more willing to adopt it.
You kinda have to use nightly to really enjoy using Rust.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:18
You mean it's not as stable as a decades old language? XD
Sean Perry
@shaleh
May 03 2016 17:19
as for C++11, I am too used to working with coders who refuse to use exceptions and are not sure they trust the STL, much less Boost and friends.
Daniel Collin
@emoon
May 03 2016 17:19
C++xx still suffers from C++ legacy and always will.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:19
@shaleh
Oh God, you poor, poor perseon. I'm so sorry.
Daniel Collin
@emoon
May 03 2016 17:19
We don’t use exceptions, have own STL and if anyone mentions boost they will get thrown out.
Sean Perry
@shaleh
May 03 2016 17:20
then again, I did wedge the C++ runtime into a binary so I could run C++ in EFI :-)
LeonineKing1199
@LeonineKing1199
May 03 2016 17:20

We don’t use exceptions, have own STL and if anyone mentions boost they will get thrown out.

*vomits profusely*

Sean Perry
@shaleh
May 03 2016 17:21
^^ every job I have had where C++ was used.
shaleh @shaleh is happily a Python hacker these days
LeonineKing1199
@LeonineKing1199
May 03 2016 17:21
Okay, it's official. I'm thanking my lucky stars that I never actually got a job in C++ because I think it would kill my love of the language.
Daniel Collin
@emoon
May 03 2016 17:21
adding boost would make compile and link/times skyrocket.
Sean Perry
@shaleh
May 03 2016 17:22
not as bad as you think
LeonineKing1199
@LeonineKing1199
May 03 2016 17:22
I think you can pre-compile some of the headers though, or that was told to me when I complained about the compile times too
Sean Perry
@shaleh
May 03 2016 17:22
smart including helps a lot
Daniel Collin
@emoon
May 03 2016 17:22
also C++ templates is awful
LeonineKing1199
@LeonineKing1199
May 03 2016 17:22
Eh, templating is ugly as hell but std::enable_if is kind of a God-send
Daniel Collin
@emoon
May 03 2016 17:22
@shaleh have you tried it in a code base with like 4+ milion lines of code?
Sean Perry
@shaleh
May 03 2016 17:22
awful. Naw. A Ridiculous amount of typing and fragile slowing down agile coding. Yes.
hmm, 4m. No. I think largest I tried boost in was a million or so.
LeonineKing1199
@LeonineKing1199
May 03 2016 17:23
You must have at least +16 agility to code XD
Daniel Collin
@emoon
May 03 2016 17:23
awful syntax, awful for debugging, makes debug builds very slow, etc, etc
LeonineKing1199
@LeonineKing1199
May 03 2016 17:23
Well, that's what concepts aim to solve
Sean Perry
@shaleh
May 03 2016 17:23
C++ would not be usable without them though
LeonineKing1199
@LeonineKing1199
May 03 2016 17:23
enable_if is a good band-aid until then
Daniel Collin
@emoon
May 03 2016 17:23
yes it would
LeonineKing1199
@LeonineKing1199
May 03 2016 17:23
Actually, I think all major compiler vendors implement concepts as of now
I know GCC does in 6.1 or w/e
Btw, you guys are fun to talk to! I haven't had a gitter discussion this engaging yet!
emoon @emoon looks at topic. Time to not talk more C++.
Zakarum
@omni-viral
May 03 2016 17:49
Actually I'm not sure many C++ programmers would be against Rust when it'll stabilized.
Definitely not me. Many C++ features are cool but you have to re-check everything. Rust's borrow-checking, lifetimes, move-semantics together make you sure that everything is OK with memory.
I have to support old C++ code on my job and it is awful. Nobody knows what is going on there (no code-review or something). Data-races, dead-locks. Dead-locks that appear after solving data-races in another module. Rust can solve some of those problems. I hope )
Zakarum
@omni-viral
May 03 2016 17:58
You know what takes more time for compile that boost? Whole project recompilation because you put everything in single Utils.dll. And even worse, every header of project in "stdafx.h"
LeonineKing1199
@LeonineKing1199
May 03 2016 17:59
Well, your first problem was doing C++ on Windows, right there
Windows is like the anti-programming OS
meme
@meme
May 03 2016 17:59
I try to avoid C++ as best I can, I've really only written it twice for binding reasons so that I could use C++ projects in other languages. I wouldn't write it otherwise. Rust would be my first pick.
Peter Atashian
@retep998
May 03 2016 18:12
@LeonineKing1199 Not really. You can program perfectly fine on Windows. Just because there's a lot of bad tools that are Windows specific does not make Windows a terrible place to program
meme
@meme
May 03 2016 18:13
It's not ideal for programming, but you can make it work with some effort
Peter Atashian
@retep998
May 03 2016 18:13
"not ideal" simply means it isn't ideal for someone's preferred development methods
LeonineKing1199
@LeonineKing1199
May 03 2016 18:17
The hardest thing I had to do at my current job was install a C++ compiler on Windows.
You can't just install a C++ compiler, it seems.
meme
@meme
May 03 2016 18:18
Run a VM ;)
Sean Perry
@shaleh
May 03 2016 18:19
Visual Studio is the compiler. I have a chocolatey script to install it on new VMs. No big deal :-)
LeonineKing1199
@LeonineKing1199
May 03 2016 18:20

That's what I hate. I had to wind up installing Visual Studio (of which there's like 5 versions) and even then, I had to wind up creating a new project just to get the compiler to install and become part of my system.

Idk if I'm spoiled or not but, man, sudo apt-get install g++ is pretty nice.

Sean Perry
@shaleh
May 03 2016 18:21
LeonineKing1199
@LeonineKing1199
May 03 2016 18:21

Scripts based on chocolatey to setup a Windows box to actually be usable.

I lol'd XD
:plus1:

Sean Perry
@shaleh
May 03 2016 18:21
@LeonineKing1199 discover the new packaging system for Windows :-)
Sean Perry
@shaleh
May 03 2016 18:28
@LeonineKing1199 https://chocolatey.org/
Peter Atashian
@retep998
May 03 2016 18:38
@LeonineKing1199 You can actually install just the msvc build tools now, which skips visual studio entirely and just gives you the C++ compilers and SDKs
LeonineKing1199
@LeonineKing1199
May 03 2016 18:38
Where was this 7 months ago?!?!?!
Peter Atashian
@retep998
May 03 2016 18:39
Still in internal development at Microsoft? :P
wow
desperate times, measures and all that...
Zakarum
@omni-viral
May 03 2016 20:29
Well. I never chose it. But everyone around me seems happy with Visual Studio 2008 with all bugs in it. Developing a little feature for few month while introducing bugs in every part of system?!?! "OK. That is just what programming meant to be" was the answer to me.
Peter Atashian
@retep998
May 03 2016 20:51
2008? Why would anyone intentionally use such an old version of VS? We've already had 2010, 2012, 2013, 2015, and they already have a preview for the next version
Zakarum
@omni-viral
May 03 2016 21:29
@retep998 Same reason we use HDDs instead of SDDs. New version costs money.
Peter Atashian
@retep998
May 03 2016 21:31
Well, I suppose in an enterprise scenario if you have a really cheap company which doesn't want to invest in software...
For anything other than enterprise though community edition is totally free
Zakarum
@omni-viral
May 03 2016 21:33
@retep998 not more than 5 developers can use community edition. Event if company is small
we have 11
Zakarum
@omni-viral
May 03 2016 21:39
When people mutate elements of std::set in-place and write macro like DECLARE_SMART_POINTER(TypeName, VarName); which expnads to SmartPointer<TypeName> VarName;
You don't try to fix it
You try to find another place to work
LeonineKing1199
@LeonineKing1199
May 03 2016 21:41
How are they mutating elements in-place? Does std::set return references?
Or are they doing some crazy placement new shit?
I haven't used std::set in ages
Zakarum
@omni-viral
May 03 2016 21:45
@LeonineKing1199 in VS2008 implementation it returns non-const iterators
LeonineKing1199
@LeonineKing1199
May 03 2016 21:47
Looks like it's part of the standard though to return a choice between mutable and immutable iterators though.
Zakarum
@omni-viral
May 03 2016 22:01
@LeonineKing1199 but changing value violate whole tree. I'm pretty sure you can't do that with C++0x.
With all nonsense in C++03... may be you can even change set elements
LeonineKing1199
@LeonineKing1199
May 03 2016 22:09
Gah, if I didn't have so much to do, I'd love to try and replicate that code lol.
mhsjlw
@mhsjlw
May 03 2016 22:32
Hello, I'm back, with yet another question :D. I'm implementing a previously designed protocol and it has to work the same (obviously) but it does this stupid thing where it has a max string length of 64 and if it isn't that size it pads it with spaces (0x20, or 0x32? I can't remember lol) I have this code:
impl<T> MCString for Cursor<T> {
  fn read_mc_string(&mut self) -> String {
    let mut bytes = Vec::new();
    bytes.resize(64, 0);
    self.read_exact(&mut bytes[..]).unwrap();

    let mut length: usize = 0;

    bytes.reverse();

    for i in 0..bytes.len() {
      if *bytes.get_mut(i).unwrap() != 0x20 {
        length = i;
        break;
      }
    }

    let mut splitted = bytes.slice_from(length).to_vec();
    splitted.reverse();
    return String::from_utf8(splitted.slice_from(0).to_vec()).unwrap();
  }
}
I get this error:
src/mc_string.rs:48:10: 48:20 error: no method named `read_exact` found for type `&mut std::io::cursor::Cursor<T>` in the current scope
src/mc_string.rs:48     self.read_exact(&mut bytes[..]).unwrap();
but a quick glance at the rust docs indeed confirm that read_exact is a method that can be executed on Cursor
My imports are as follows:
use std::net::TcpStream;
use byteorder::{ BigEndian, ReadBytesExt, WriteBytesExt };
use std::io::BufReader;
use std::io::Read;
use std::io::Cursor;
use std::io::Write;
any ideas ?
also it seems that .reverse(); isn't a function so I'll leave that as a place holder but if anyone can also provide an alternative that would be appreciated :D
Ivan Ivashchenko
@defuz
May 03 2016 22:38

@mhsjlw look at the implementation of Read for Cursor<T>:

impl<T> Read for Cursor<T> where T: AsRef<[u8]>

I think you shoud add the same condition T: AsRef<[u8]> for your impl

Ivan Ivashchenko
@defuz
May 03 2016 22:44
@mhsjlw instead of reversing Vec you may use Iterator::rev function for double ended iterators
@mhsjlw btw, there is reverse function for slices, so i think something like &mut splitted.reverse() should work.
mhsjlw
@mhsjlw
May 03 2016 22:53
I'll give that all a try, thanks
Zakarum
@omni-viral
May 03 2016 22:53
This message was deleted
mhsjlw
@mhsjlw
May 03 2016 22:54
@SCareAngel if you have anything you want to add, please do
@defuz
src/mc_string.rs:31:5: 31:23 error: the type of this value must be known in this context
src/mc_string.rs:31     splitted.reverse();
I think it's a type error when using reverse ?
Zakarum
@omni-viral
May 03 2016 22:56
Add type declaration to splitted
mhsjlw
@mhsjlw
May 03 2016 23:01
yeah adding the Vec<u8> type seemed to remove that error
when did slice_from get removed ?
why is that an error ?
Any ideas for alternatives? I'm still stuck back in the day when we had MemReaders :P
Zakarum
@omni-viral
May 03 2016 23:09
Here what I can propose )
impl<T: AsRef<[u8]>> MCString for Cursor<T> {
  fn read_mc_string(&mut self) -> String {
    let mut bytes = vec![0; 64];
    self.read_exact(&mut bytes[..]).unwrap();

    match bytes.iter().rposition(|e| *e == 0x20) {
        Some(pos) => { bytes.resize(pos, 0); }
        None => {}
    };

    return String::from_utf8(bytes).unwrap();
  }
}
mhsjlw
@mhsjlw
May 03 2016 23:13
that's a way way way nicer approach
I need to start thinking like rustacean
Zakarum
@omni-viral
May 03 2016 23:17
@mhsjlw why 64 bytes?
What if there not mulitple of 64 bytes in T?
mhsjlw
@mhsjlw
May 03 2016 23:18
I didn't design the protocol :P
Zakarum
@omni-viral
May 03 2016 23:18
What if 0x20 is part of string you need actually?
mhsjlw
@mhsjlw
May 03 2016 23:18
hmm
crap it is
yeah, cause there can be spaces
so we only want to trim of the ending
*off
hmm
Zakarum
@omni-viral
May 03 2016 23:20
one moment
Zakarum
@omni-viral
May 03 2016 23:25
impl<T: AsRef<[u8]>> MCString for Cursor<T> {
  fn read_mc_string(&mut self) -> String {
    let mut bytes = Vec::new();
    self.take(64).read_to_end(&mut bytes).unwrap();

    match bytes.iter().rposition(|e| *e != 0x20) {
        Some(pos) => { bytes.resize(pos+1, 0); }
        None => {}
    };

    return String::from_utf8(bytes).unwrap();
  }
}
mhsjlw
@mhsjlw
May 03 2016 23:27
cool!
what does rposition do?
is it like a forEach?
Zakarum
@omni-viral
May 03 2016 23:27
It defined only for DoubleEndedIterator
iterates from end to begin and search for element that match predicate
and returns position of that element
So in this code it should find first nonspace at the end and return its position
mhsjlw
@mhsjlw
May 03 2016 23:29
so very cool, thank you
now that i've got the networking stuff I've been starting on the logic
I've got a loop that accepts connections splits them into threads then handles each and every packet
but for some strange reason, when I read the packet, the packet_id field doesn't exist?
but I looked at the code and it's all good
src/main.rs:40:19: 40:35 error: attempted access of field `packet_id` on type `core::result::Result<packets::Packet, std::io::error::Error>`, but no field with that name was found
src/main.rs:40         } else if packet.packet_id == 0x05 {
and yes I know, I will use matching in a sec
right now I'm just doing debugging :P
pub struct Packet {
  pub packet_id: u8,
  pub data: Vec<u8>
}
packet does have packet_id
and I import it too
use packets::{ Packet, MCPackets };
Zakarum
@omni-viral
May 03 2016 23:31
Result<Packet> does not have packet_id
mhsjlw
@mhsjlw
May 03 2016 23:31
but it must
Zakarum
@omni-viral
May 03 2016 23:31
Nope
mhsjlw
@mhsjlw
May 03 2016 23:31
ah
Ok(Packet {
      packet_id: packet_id,
      data: data
    })
so there is an error then ?
because it never Oks ?
pub fn receive(mut conn: TcpStream) -> ::std::io::Result<Packet> {
    let packet_id = conn.read_u8().unwrap();

    let packet_len = match packet_id {
      0x00 => 130,
      0x05 => 8,
      0x08 => 9,
      0x0d => 65,
      _ => 0
    };

    let mut data = Vec::new();
    data.resize(packet_len, 0);
    try!(conn.read_exact(&mut data[..]));

    Ok(Packet {
      packet_id: packet_id,
      data: data
    })
  }
Zakarum
@omni-viral
May 03 2016 23:32
Result<Packet> have no fields of Packet
You have to match it
mhsjlw
@mhsjlw
May 03 2016 23:32
I'm confused...
ah
I think I know what you mean?
match packet.packet_id {
    Ok(v) => do stuff with packetid
    Err(e) => oops i got a problem
}
is that the idea?
Zakarum
@omni-viral
May 03 2016 23:33
Yeap
mhsjlw
@mhsjlw
May 03 2016 23:33
nice !
i'm getting better ;)
thank you
I must say that is an interesting approach on error handling...
I like it ;D
Zakarum
@omni-viral
May 03 2016 23:34
match packet.packet_id replace with match packet
mhsjlw
@mhsjlw
May 03 2016 23:34
ok
can I match within a match?
Zakarum
@omni-viral
May 03 2016 23:35
This approach was stolen from functional languages )
you can match within anything
even function call
foo(match somethin { ... }, another_argument);
because match .. {...} is expression
as x + y
mhsjlw
@mhsjlw
May 03 2016 23:36
    loop {
        let packet = Packet::receive(conn);

        match packet {
            Ok(v) => println!("{}", packet.packet_id),
            Err(e) => println!("error: {:?}", e),
        }
}
src/main.rs:28:37: 28:53 error: attempted access of field `packet_id` on type `core::result::Result<packets::Packet, std::io::error::Error>`, but no field with that name was found
src/main.rs:28             Ok(v) => println!("{}", packet.packet_id),
                                                   ^~~~~~~~~~~~~~~~
what am I doing wrong now >_<
packet_id should exist now, right ?
Zakarum
@omni-viral
May 03 2016 23:37
loop {
        let packet = Packet::receive(conn);

        match packet {
            Ok(v) => println!("{}", v.packet_id),
            Err(e) => println!("error: {:?}", e),
        }
}
mhsjlw
@mhsjlw
May 03 2016 23:37
wow, that was stupid mistake
:P
thank you
Zakarum
@omni-viral
May 03 2016 23:38
And don't forget to break from loops sometimes )
mhsjlw
@mhsjlw
May 03 2016 23:38
yeah which is the all case ?
Zakarum
@omni-viral
May 03 2016 23:38
In Err (..) => for example
mhsjlw
@mhsjlw
May 03 2016 23:38
_ ?
Zakarum
@omni-viral
May 03 2016 23:38
_ ? WAT?
mhsjlw
@mhsjlw
May 03 2016 23:38
lmao
yeah I'm right
_ => println!("something else"),
it's like the catch other
Zakarum
@omni-viral
May 03 2016 23:39
Yeah. You can use _ to handle anything in match
mhsjlw
@mhsjlw
May 03 2016 23:40
awesome ;)
Zakarum
@omni-viral
May 03 2016 23:40
You definitely should read match chapter
Ivan Ivashchenko
@defuz
May 03 2016 23:40
but it’s not idiomatic in this case. explicit variants Ok(..) and Err(..) are preferred
mhsjlw
@mhsjlw
May 03 2016 23:41
@SCareAngel I left off on that chapter, rofl
@defuz good to know, thanks
Rust's ownership system still confuses me >_<
Zakarum
@omni-viral
May 03 2016 23:43
@defuz is right. _ makes sense only when you have really nothing to do with variants left
mhsjlw
@mhsjlw
May 03 2016 23:44

say conn = mut TcpStream

let packet = Packet::receive(conn);

and yet

use of moved value: `conn`

but when I .copy() conn it says that the .copy function doesn't exist

Zakarum
@omni-viral
May 03 2016 23:44
@mhsjlw ownership itself in Rust is pretty easy. Almost everything use move-semantics by default
because it called clone()
mhsjlw
@mhsjlw
May 03 2016 23:45
wow I really misread that
no sorry
I wrote that wrong
Zakarum
@omni-viral
May 03 2016 23:45
but you shouldn't clone tcpstream
mhsjlw
@mhsjlw
May 03 2016 23:45
my code is .clone()
@SCareAngel how should I pass it to receive then?
Zakarum
@omni-viral
May 03 2016 23:46
not everything is clonnable
mhsjlw
@mhsjlw
May 03 2016 23:46
et packet = Packet::receive(conn.clone());
*let
and remove that .clone()
Zakarum
@omni-viral
May 03 2016 23:46
let packet = Packet::receive(&conn);
mhsjlw
@mhsjlw
May 03 2016 23:46
Yeah I've tried that too
Zakarum
@omni-viral
May 03 2016 23:46
pass the reference
mhsjlw
@mhsjlw
May 03 2016 23:46
src/main.rs:25:34: 25:39 error: mismatched types:
 expected `std::net::tcp::TcpStream`,
    found `&std::net::tcp::TcpStream`
(expected struct `std::net::tcp::TcpStream`,
    found &-ptr) [E0308]
src/main.rs:25     let packet = Packet::receive(&conn);
pub fn receive(mut conn: TcpStream) -> ::std::io::Result<Packet> {
so maybe I need &TcpStream?
does that make sense?
or is t &mut?
Zakarum
@omni-viral
May 03 2016 23:47
exactlty
&mut may fit
mhsjlw
@mhsjlw
May 03 2016 23:47
&TcpStream
seems to do it
@SCareAngel yeah I'm starting to get the hang of this
cool
Zakarum
@omni-viral
May 03 2016 23:48
it was mut conn: TcpStream so I suppose you use some mut methods
So you may be just have to make it &mut TcpStream
Whenever you write new function, try ask least possible from it's arguments.
Every argument should be arg: &T by default.
If you have to use some function inside that require arg: &mut T so your function shall ask this argument that way
And only if you gonna destroy that value or pass it anywhere than you make it arg: T
Same goes for types of arguments actually
mhsjlw
@mhsjlw
May 03 2016 23:55
how can I accept a struct as an argument?
Packet: packet doesn't seem to do the trick
Zakarum
@omni-viral
May 03 2016 23:56
??
mhsjlw
@mhsjlw
May 03 2016 23:56
fn handle_connection(mut conn: TcpStream) {
  println!("connection");

  loop {
    let packet = Packet::receive(&conn);

    match packet {
      Ok(packet) => handle_packet(packet, &conn),
      Err(error) => println!("error: {}", error),
    }
  }
}
once I get a packet, I send it to handle_packet
so that handle_packet can use the fields and send back packets as needed
Zakarum
@omni-viral
May 03 2016 23:56
what the error?
mhsjlw
@mhsjlw
May 03 2016 23:56
fn handle_packet(Packet: packet, mut conn: &TcpStream) {
that's the handle_packet
type name `packet` is undefined or not in scope [E0412]
src/main.rs:34 fn handle_packet(Packet: packet, mut conn: &TcpStream) {
oh lmao
never mind
Zakarum
@omni-viral
May 03 2016 23:57
you swap..
mhsjlw
@mhsjlw
May 03 2016 23:57
yup figured that out
Zakarum
@omni-viral
May 03 2016 23:57
)
mhsjlw
@mhsjlw
May 03 2016 23:57
ok I am going to exit the chat before I keep asking stupid questions
thank you all, for all of your help
Zakarum
@omni-viral
May 03 2016 23:57
you're walcome
mhsjlw
@mhsjlw
May 03 2016 23:57
I appreciated it a lot
*appreciate