These are chat archives for rust-lang/rust

4th
Sep 2018
Olson3R
@Olson3R
Sep 04 2018 03:08
Has anyone worked with an IMU (accelerometer, gyro, magnetometer, http://a.co/d/hZ5PWZ0) from a raspberry pi with Rust?
Sam Johnson
@sam0x17
Sep 04 2018 09:53
is there some way I can initialize an array of 512 u8's other than doing [0u, 0u, 0u, ...] 512 times?
context:
struct Stream {
    buffer: [u8; 512]
}

impl Stream {
    fn default() -> Stream {
        Stream {
            buffer: // ??
        }
    }
}
Zakarum
@omni-viral
Sep 04 2018 09:56
@sam0x17 let array: [u8; 512] = [0; 512];
Sam Johnson
@sam0x17
Sep 04 2018 09:58
yay, thank you @omni-viral @rw
Sam Johnson
@sam0x17
Sep 04 2018 10:30
how can I print something like this? let buffer: [u8; 512] = [0, 512];
Zakarum
@omni-viral
Sep 04 2018 10:31
print?
like print!?
Sam Johnson
@sam0x17
Sep 04 2018 10:31
as in I want to debug print that array
Zakarum
@omni-viral
Sep 04 2018 10:31
[T; 512] doesn't implement Debug
But you can coerse &[T; N] into &[T] and print it
Sam Johnson
@sam0x17
Sep 04 2018 10:32
ah ok thank you
Zakarum
@omni-viral
Sep 04 2018 10:32
let buffer: [u8; 512] = [0; 512];
println!("{:#?}", buffer[..]);
@rw 's example already does this btw
trsh
@trsh
Sep 04 2018 12:00
I have this code in C
char xx[100] = "";
        soap_sprint_fault(soap, xx, 100);

        printf("s = %s", xx);
That gives me "s = SOAP 1.1 fault SOAP-ENV:Server [no subcode]
"Host not found""
Howerver in rust
if !sr.xx.is_null() {
        use std::ffi::CStr;
        unsafe {
            println!("xx:{:?}", CStr::from_ptr(sr.xx).to_str().unwrap());
        }
    }
"xx:"\u{1}""
Any ideas?
trsh
@trsh
Sep 04 2018 12:40
If I extned xx size to 150
"s = SOAP 1.1 fault SOAP-ENV:Server [no subcode]
"Host not found"
Detail: get host by name failed in tcp_connect()
thread '<unnamed>' panicked at 'called Result::unwrap() on an Err value: Utf8Error { valid_up_to: 1, error_len: Some(1) }', libcore/result.rs:945:5
"
Zakarum
@omni-viral
Sep 04 2018 12:43
You mean you can't convert from C-string to CStr?
trsh
@trsh
Sep 04 2018 12:43
Setting a huger number fixed the problem
Zakarum
@omni-viral
Sep 04 2018 12:43
Try with CStr::to_string_lossy

thread '<unnamed>' panicked at 'called Result::unwrap() on an Err value: Utf8Error { valid_up_to: 1, error_len: Some(1) }',

I can't see that it is fixed

trsh
@trsh
Sep 04 2018 12:45
Yeah, but I can't guess the length
So just set something huge?
Zakarum
@omni-viral
Sep 04 2018 12:46
I can't follow. When you get a panic and when you get "\u{1}"?
Typically documentation say how to choose size of the array.
Either there is a limit.
Or method to obtain size required
trsh
@trsh
Sep 04 2018 12:47
I guess 100 is not enough, 150 cuts some UTF sym in middle
So with 100 I got trash, with 150 panic
1500 everything fine :D
Zakarum
@omni-viral
Sep 04 2018 12:48
Do you have a link for docs?
trsh
@trsh
Sep 04 2018 12:48
100 + lossy also produces trash > xx:"\u{3}�\u{0}\u{0}\u{0}\u{0}"
"Use soap_sprint_fault(struct soap, char buf, size_t len) to print the error to a string, "
Thats it :D
Zakarum
@omni-viral
Sep 04 2018 12:50
From the code I see that this function fills buf with either strncpy or snprintf
Both functions just discard characters if len is too small
So you get a garbage not because of the length
How do you obtain sr.xx?
I have a feeling that you read garbage because xx in C doesn't live long enough
And you see that everything is OK with large buffer because only few last bytes of it gets rewritten when you print it on Rust side
But in fact it is UB
trsh
@trsh
Sep 04 2018 12:56
I have a feeling that you read garbage because xx in C doesn't live long enough
How I can make it live longer
Zakarum
@omni-viral
Sep 04 2018 12:56
Does the C code from your snippet is part of the function you call from Rust
and after calling that function you print sr.xx?
C
Should live in C
Zakarum
@omni-viral
Sep 04 2018 12:58
Yeah. You see. Result aa = { xx, ... }. Here you store pointer to stack in struct.
Then return aa;
xx doesn't exists after that statement
trsh
@trsh
Sep 04 2018 13:00
brrr
Zakarum
@omni-viral
Sep 04 2018 13:00
aa.soap_error is now invalid pointer. Reading it is UB. You can read garbage. You can read what you expected. The app can eat your laundry
trsh
@trsh
Sep 04 2018 13:00
So Ok im C noob, so how do I?
Zakarum
@omni-viral
Sep 04 2018 13:01
Provide buffer from Rust side
trsh
@trsh
Sep 04 2018 13:01
persist xx and still return the struct
Zakarum
@omni-viral
Sep 04 2018 13:01
Unfortunately you can't move array in C as you can do in Rust
Another option is to make Result contain an array
struct Result {
   char soap_error[256];
   struct ns2__AddressValidationReply AddressValidationReply;
}
Instatiate Result and write error there soap_sprint_fault (soap, result.soap_error, 256)
trsh
@trsh
Sep 04 2018 13:04
let's try
Zakarum
@omni-viral
Sep 04 2018 13:04
On rust side you'll make
struct Result {
   soap_error: [libc::c_char; 256],
   ...
}
And use CStr::from_ptr(result.soap_error.as_ptr()).to_str()
trsh
@trsh
Sep 04 2018 13:07
Instatiate Result and write error there
But what to provide?
For err?
""?
Zakarum
@omni-viral
Sep 04 2018 13:08
{ 0 }
Or ""
trsh
@trsh
Sep 04 2018 13:09
{ 0 } This looks like something
:D
Zakarum
@omni-viral
Sep 04 2018 13:10
I have no idea what you're talking about
trsh
@trsh
Sep 04 2018 13:10
:D
@omni-viral any example by hand how to use soap_error: [libc::c_char; 256], empty or not empty, etc?
Zakarum
@omni-viral
Sep 04 2018 13:13
CStr::from_ptr(result.soap_error.as_ptr()).to_str()
trsh
@trsh
Sep 04 2018 13:16
I guess it can't be NULL in this impl
Zakarum
@omni-viral
Sep 04 2018 13:16
How do you expect pointer to an actual array to be NULL?
trsh
@trsh
Sep 04 2018 13:18
Well char *soap_error can be set to NULL
However tnx, stuff seems to work
trsh
@trsh
Sep 04 2018 13:29
Strange thing. Despite I icreased count on both sides to 1024
I have short at the end cut text
Will debug, maybe some foulty code of mine
Strange: xx:"und\"\nDetail: get host by name failed in tcp_connect()\n"
Zakarum
@omni-viral
Sep 04 2018 13:42
There is no char *soap_error. It is char soap_error[256] now
trsh
@trsh
Sep 04 2018 13:42
And there are some probs
Even with huge char count its cut off
On C its fine
Zakarum
@omni-viral
Sep 04 2018 13:43
It must be cut at the end if string doesn't fit
trsh
@trsh
Sep 04 2018 13:43
it doesn't fit in 1024?
Don't think so
Zakarum
@omni-viral
Sep 04 2018 13:44
You should see first 1024 chars though
Did you add #[repr(C)] onto struct Result in rust?
If not then you potentially (and I guess actually) have Result in rust with different layout
trsh
@trsh
Sep 04 2018 13:45
Increaed even more
struct Result
{
    char soap_error[2024];
    struct ns2__AddressValidationReply AddressValidationReply;
};
Same
Zakarum
@omni-viral
Sep 04 2018 13:48
@trsh what about #[repr(C)]?
trsh
@trsh
Sep 04 2018 13:48
very UB'ish
Zakarum
@omni-viral
Sep 04 2018 13:48
?
trsh
@trsh
Sep 04 2018 13:48
struct Resi {
    soap_error: [libc::c_char; 2024],
    AddressValidationReply: ns2__AddressValidationReply,
}
Zakarum
@omni-viral
Sep 04 2018 13:49
#[repr(C)]
struct Resi {
    soap_error: [libc::c_char; 2024],
    AddressValidationReply: ns2__AddressValidationReply,
}
And cut size down to 256 on both sides
Using non-repr(C) structs with FFI is UB.
trsh
@trsh
Sep 04 2018 13:50
Damn, right, tnx
Ash
@ashthespy
Sep 04 2018 15:39

Hi! I have a question about using futures from a thread. I spawn a new thread, and pass it a futures::sync::mpsc::UnboundedReceiver. But I don't see how I can poke this future to receive some the passed messages on this new thread.

I have tried:

impl TestThread {
    fn run(mut self) {
        let now = SystemTime::now();
           loop {
           thread::sleep(Duration::from_millis(2000));
            println!(
                "Thread tick[]: {:?}",
                now.elapsed().unwrap().as_secs()
            );
            match self.channel_rx.poll().unwrap() {
                Ok(msg) => println!("Msg: {:?}", msg),
                _ => (),
            }
        }
    }
}

This doesn't seem to work - it rightfully panics with a no Task is currently running
How would one go about this??

Zakarum
@omni-viral
Sep 04 2018 16:00
Futures aren't designed to be polled directly, except from wrapping future
You need to spawn a task from it
There must be spawn function
Ash
@ashthespy
Sep 04 2018 16:12
I have got around this by let (msg, channel_rx) = self.channel_rx.into_future().wait().unwrap();
I don't follow your lead - I know I can poll the channel from a future - but I want to pass this on to another thread to offload other tasks
impl TestThread {
    fn run(mut self) {
        loop {
        let (msg, channel_rx) = self.channel_rx.into_future().wait().unwrap();
        self.channel_rx= channel_rx;
        match msg{
            Some(event) => self.handle_event(msg),
            None => return,
        }
        }
    }

    fn handle_event(&mut self, event:Event) {
        info!("Msg:: -->{:?}",msg)
    }
}
Anything wrong in doing it this way?
Ash
@ashthespy
Sep 04 2018 16:47
bear with me - but I still don't see how I can use executor::spawn with futures::sync::mpsc::UnboundedReceiver
Zakarum
@omni-viral
Sep 04 2018 16:54
In older versions it was usable with streams
Ash
@ashthespy
Sep 04 2018 16:59
would you happen to have a snippet of how one might use this?
I found the old version of the docs - https://docs.rs/futures/0.1.23/src/futures/task_impl/mod.rs.html#229-235
But I must confess I don't feel particularly smart right now :-|
Sam Johnson
@sam0x17
Sep 04 2018 17:08
what is the proper way to make a file that is entirely one struct definition? like do I have to enclose it in a module or is there a way I can just have the struct definition by itself and get that loaded?
Lyle Mantooth
@IslandUsurper
Sep 04 2018 17:47
@sam0x17, usually files map to modules, but why is a module going to have only a struct definition in it? What about impls or other functions that use that struct?
Zakarum
@omni-viral
Sep 04 2018 18:20
@ashthespy With newer futures I guess you should do:
let result = block_on(stream.for_each(|msg| { self.handle_event(msg); Ok() }));
Sam Johnson
@sam0x17
Sep 04 2018 18:32
@IslandUsurper the struct definition + the impls etc
the struct is named Stream so I wanted to avoid having stream::Stream so I was hoping there was a way to not have it in its own module but have it still in its own file
if that makes sense
I'm used to ruby/crystal where you can just require willy-nilly
Lyle Mantooth
@IslandUsurper
Sep 04 2018 18:33
Well, I point out std::option::Option and std::result::Result.
Sam Johnson
@sam0x17
Sep 04 2018 18:33
ah ok so that's a rust thing and not bad
Lyle Mantooth
@IslandUsurper
Sep 04 2018 18:33
You dont' see them written out much because they're automatically included by the prelude.
Sam Johnson
@sam0x17
Sep 04 2018 18:34
kk ty
Lyle Mantooth
@IslandUsurper
Sep 04 2018 18:34
use stream::Stream; in all your files, and you can get avoid most of the duplication.
Sylwester Rąpała
@xoac
Sep 04 2018 21:04
Hi, I would like to deserialize a struct struct MyStruct { a: [u32; 64] } And I want a can be filled from 0 to 64 and the rest is filled with Default::default
Do I need implement own deserializer?
Brad Gibson
@U007D
Sep 04 2018 22:14
is it possible to conditionally apply #![warn(foo)] to set a lint to warn, crate-wide but only when compiling for release?