These are chat archives for rust-lang/rust

17th
Jan 2019
aohan237
@aohan237
Jan 17 03:57
hi
a question trike me,and i cant explain it
the question is
unsafe code is Inevitable ,why don't you use c++? what's the reason of we use rust?
can someone have a detailed explaination?
earthengine
@earthengine
Jan 17 04:09
It is far from inevitable
I was always using safe code until recently I have to work on Pin types.
I would say 99% of my time in Rust is in the safe zone.
Tim Vermeulen
@timvermeulen
Jan 17 04:13
and if you really need unsafe code, you can isolate it and give it a safe interface, which makes auditing it really easy compared to C++ where all code is unsafe unsafe code could be anywhere
Nils 'bash0r' Jonsson
@aka-bash0r
Jan 17 04:22
@1tgr Thanks, the semicolon at the end was a typo. :>
Denis Lisov
@tanriol
Jan 17 07:49
@aohan237 For me personally the main reason is that Rust makes a more coherent picture. C++ is layers over layers over layers of history, and keeping to the "known safe" parts requires knowing their boundaries and thinking about that.
And, yes, my personal policy for my (work) projects is no unsafe code in my project unless absolutely required. So far FFI was the only case where I had to write unsafe code; everything else either works ok with safe code only, or uses some safe abstraction that probably has some unsafe underneath, but isolates my code from it.
toxicafunk
@toxicafunk
Jan 17 08:45
anyone know of a rust docker image on alpine?
Denis Lisov
@tanriol
Jan 17 08:48
Do you mean an image with the Rust compiler to build software or something else?
toxicafunk
@toxicafunk
Jan 17 08:51
rust compiler and cargo iguess
i'm thinking it should be easy to build one but maybe there is one already who've taken care of things I haven't considered
Ryan
@Yarn
Jan 17 09:13
no idea if it's any good but blind googling got me https://hub.docker.com/r/frolvlad/alpine-rust
toxicafunk
@toxicafunk
Jan 17 09:15
nice, thx
in case anyone else is taking notes :)
wegry
@wegry
Jan 17 13:14
Is it possible to start a static file server, while also listening to the file system with something like https://docs.rs/notify/4.0.6/notify/?
And do folks have a recommendation for a lightweight static file server to embed alongside this file system watcher?
Something like https://hyper.rs/ looks like it blocks on startup?
toxicafunk
@toxicafunk
Jan 17 13:16
u can combine hyper with other tokyo futures
let consumer = consumer::run_async_processor(...);

    pretty_env_logger::init();
    let addr = ([127, 0, 0, 1], port).into();
    let server = Server::bind(&addr)
        .serve(|| service_fn(server::router))
        .map_err(|e| eprintln!("server error: {}", e));
something like this
where consumer is impl Future<Item=(), Error=()>
wegry
@wegry
Jan 17 13:19
Hmmm, I need my notification lib to return a future somehow then...
toxicafunk
@toxicafunk
Jan 17 13:20
that's one way to do it
wegry
@wegry
Jan 17 13:20
Can I just fire and forget the infinite loop?
toxicafunk
@toxicafunk
Jan 17 13:20
if uŕe not using anything tokyo related u can still just run a separate threads
let app = consumer.join(server).map(|_| ());

    info!("Starting application");
    tokio::run(lazy(|| app))
that's all Iḿ doing
wegry
@wegry
Jan 17 13:21
I'm not using tokyo yet. But thanks for the help. I'll give that a shot
toxicafunk
@toxicafunk
Jan 17 13:22
i mean, hyper uses tokyo, thatś why i mention it
wegry
@wegry
Jan 17 13:23
Good to know. Isn't there a competing http server setup with Rocket?
I really only need a static file server, so I'm not sure about a whole web framework
toxicafunk
@toxicafunk
Jan 17 13:25
was in your exact same position a few weeks ago
but hyper ended up minimalistic enough for my use case
wegry
@wegry
Jan 17 13:26
:thumbsup:
wegry
@wegry
Jan 17 14:18
@toxicafunk I'm trying to go through the hyper tutorial, but it looks like the echo example breaks down. Do I need to be on nightly or something?
use futures::Future;
use hyper::service::service_fn;
use hyper::{Body, Request, Response, Server};
use hyper::{Method, StatusCode};

const PHRASE: &str = "Hello, World!";

// Just a simple type alias
type BoxFut = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;

fn echo(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {
        (&Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }
        (&Method::POST, "/echo") => {
            // we'll be back
        }
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

pub fn static_files() {
    // This is our socket address...
    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(echo))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Started server at http://{}", addr);
    hyper::rt::run(server)
}
error[E0433]: failed to resolve: use of undeclared type or module `future`      
  --> cli/src/server.rs:26:14                                                   
   |                                                                            
26 |     Box::new(future::ok(response))                                         
   |              ^^^^^^ use of undeclared type or module `future`              

error[E0277]: the size for values of type `dyn futures::future::Future<Item=http::response::Response<hyper::body::body::Body>, Error=hyper::error::Error> + std::marker::Send` cannot be known at compilation time
  --> cli/src/server.rs:26:5                                                    
   |                                                                            
26 |     Box::new(future::ok(response))                                         
   |     ^^^^^^^^ doesn't have a size known at compile-time
For the life of me, I can't figure out what module future is supposed to be. Is it within futures or hyper?
Nvm, it's in futures...
toxicafunk
@toxicafunk
Jan 17 14:26
sorry, just read this
u got it to work?
Zakarum
@omni-viral
Jan 17 14:38
Sometimes I wonder why didn't they change the name to future
toxicafunk
@toxicafunk
Jan 17 14:41
something something quantum mechanics and parallel universes???
Matteo Ferretti
@ZER0
Jan 17 14:52
Hi there, I'm struggling to port in Rust idioms a structure that is based on inheritance; I'd like to have some advice about what is the right way
Basically I was trying to model something like the DOM tree in Rust, where you have a Node, then TextNode and ElementNode that "inherits" from it, and other "classes" like Div that inherits from ElementNode for example. Since I know there is no inheritance I was wondering how to translate efficiently a structure like that in Rust.
Ichoran
@Ichoran
Jan 17 14:56
@ZER0 - Sometimes the translation is very awkward and you need to rethink the entire purpose of the code from scratch. A lot of the time you can get by with type parameters or type members and an enum.
I find when making relatively close ports of inherited structures that I often end up writing a lot of boilerplate code, too.
Matteo Ferretti
@ZER0
Jan 17 14:59
@Ichoran my struggle is mostly about repetition. To give an example, Node could be a trait with a "node_type" field that could be an enum (e.g. NodeType::Element or NodeType::Text). I can easily implemented this value in the struct that is the final object (e.g. Body, Div, etc) however it means that for every type of element I have to write the same code.
If I do that, everything works of course, because since Div implements both Node trait and Element trait, I can pass any object to any function that requires either just Node or Element.
Tim Robinson
@1tgr
Jan 17 15:00
I don't think the nodes are separate types, I think they're cases within a single enum
toxicafunk
@toxicafunk
Jan 17 15:01
i would go for an enum instead
Tim Robinson
@1tgr
Jan 17 15:01
enum Node { /* list every HTML element */ }
toxicafunk
@toxicafunk
Jan 17 15:01
and u can add a trait that operates on Node
and each of ur types implement it
Tim Robinson
@1tgr
Jan 17 15:01
Then:
impl Node {
    fn as_text(&self) -> Option<&dyn TextNode> { ... }
}
Ichoran
@Ichoran
Jan 17 15:01
Yeah, that's what I mean by "a lot of boilerplate". You can move some common code to traits, but the core stuff has to be re-implemented unless it is so similar that it can all just go into an enum.
Matteo Ferretti
@ZER0
Jan 17 15:02
@1tgr but that's the point Node and Element are different, so Element and TextNode "shares" the same Node trait
Tim Robinson
@1tgr
Jan 17 15:03
Ok, to be more precise:
Matteo Ferretti
@ZER0
Jan 17 15:03
(Another thing could be just avoid to have Element and TextNode as trait)
Tim Robinson
@1tgr
Jan 17 15:03
enum Node {
    Element(Element),
    Text(String),
}
Don't start introducing traits until you need them (eg no Node trait, that's what enum Node is for)
Ichoran
@Ichoran
Jan 17 15:04
@ZER0 - If you use enums, you do a lot of pattern-matching to get the right implementation for the different cases. If you use structs with various traits, you tend to re-implement a lot. Neither way is great for a fairly literal port of a complex inheritance structure. It's often better to step back and rethink.
Sometimes it's just not as elegant in Rust. Rust is great and all, but if a data structure is perfectly modeled by inheritance, you generally can't make it quite as pretty without inheritance :P
Matteo Ferretti
@ZER0
Jan 17 15:06
@Ichoran, @1tgr thanks a lot, I see your point. Indeed, probably if I just clear my head and try to forget about structs and trait, and focus on enums, I might have a better approach.
Tim Robinson
@1tgr
Jan 17 15:06
It's a different way of organising types and extending their functionality, the functional model versus the OO model
Ichoran
@Ichoran
Jan 17 15:06
But, don't lose heart--there are piles of things that are not modeled very well with inheritance that you get better models of (like equality), so it's not just a limitation. And you get to skip a lot of mind-bending consideration of variance in type parameters if you don't have to worry about inheritance.
Tim Robinson
@1tgr
Jan 17 15:07
OO has open types but closed functions: I can handle any type, provided it inherits from this base class. Types have a closed set of methods (the methods on the base class)
toxicafunk
@toxicafunk
Jan 17 15:07
maybe get some inspiration from FP languages which have modelled DOM
ie. haskell or purescript
Tim Robinson
@1tgr
Jan 17 15:07
Function has closed types but open functions: I declare upfront a fixed set of data types, but anybody can write functions that operate on them
Matteo Ferretti
@ZER0
Jan 17 15:08
Don't get me wrong, I prefer avoid OO when is possible; I was just wondering how would be the "Rust Way" to model something like that – that I knew well in other domains. Thanks again
Tim Robinson
@1tgr
Jan 17 15:08
I would suggest the functional approach works here: there's a predefined set of elements in HTML, but there are lots of operations you might want to do on each one
Matteo Ferretti
@ZER0
Jan 17 15:09
@toxicafunk I checked Servo, but it didn't help – I use a DOM tree just as example of a structure that is familiar to me, I wanted basically figure out how to solve a similar problem but not quite the same.
I basically have something an interface that inherits from another interface, and so on, until it gets to the "concrete" instance; and you can pass this instance to any function that can operate to any of the intermediate interface.
But the problem, as you folks pointed out, is a lot of repetition using traits and structs. I'll see with enums: thanks again!
wegry
@wegry
Jan 17 15:12
@toxicafunk I'm good other than headers for MIME types not working ;)
Ichoran
@Ichoran
Jan 17 15:13
Often you don't actually need all those layers; may as well if you have inheritance, but if you don't, you have just the data types you actually use and just the traits that actually make sense. Not the whole gradual building up of functionality.
Victor Lopes
@vlopes11
Jan 17 18:01
Rustaceans, is it possible to use some variadic concept for trait definitions? I found some not replied old RFCs. Should be something like this
trait SomeTrait {
    fn new(index: usize, /* some variadic definition here */)
}

struct SomeStruct {}

impl SomeTrait for SomeStruct {
    fn new(index: usize, some_content: String, some_vec: Vec<i32>) {
        /* something... */
    }
}
Tim Robinson
@1tgr
Jan 17 18:02
You could have:
trait SomeTrait {
    type NewArgs;
    fn new(index: usize, args: Self::NewArgs);
}

struct SomeStruct {}

impl SomeTrait for SomeStruct {
    type NewArgs = (String, Vec<i32>);
    fn new(index: usize, args: (String, Vec<i32>)) {
        /* something... */
    }
}
Victor Lopes
@vlopes11
Jan 17 18:03
Ah, true! tuples
Yeah, that will do the trick
Thanks for the tip :)
Tim Robinson
@1tgr
Jan 17 18:03
You could assign names to the args if you used an additional struct instead of the tuple I used here
Naja Melan
@najamelan
Jan 17 19:50
is there a way to get the filename from an std::io::Error of kind NotFound?
thojest
@thojest
Jan 17 20:16
hi guys, do you know a list of some open-source projects in rust which would welcome contributing newcomers, eventhough they are just starting with Rust ?
toxicafunk
@toxicafunk
Jan 17 20:22
thojest
@thojest
Jan 17 20:23
@toxicafunk thx
verilog15
@verilog15
Jan 17 21:34
Hello! Is rust a row major order? (link: https://en.wikipedia.org/wiki/Row-_and_column-major_order)
Denis Lisov
@tanriol
Jan 17 21:37
If we're talking about arrays of arrays, yes, it's row-major. For other data structures the storage may differ.
For example, ndarray's multidimensional arrays can be either (or some hybrid if more than 2 dimensions)
Vec<Vec<T>> would be non-contiguous, but kinda row-major.
verilog15
@verilog15
Jan 17 21:42
@tanriol Can you show me a tests which proves it? Something like: print "Row" if it has row-major and "column" if column-major
Denis Lisov
@tanriol
Jan 17 22:00
Look at this snippet. No specific test for column-major, but row-major is tested.
Why do you want to know whether it's row-major?
Ichoran
@Ichoran
Jan 17 22:19
If indexing is a suffix operator, and you don't have raw support for multi-dimensional arrays (or they match the order of nested one-dimensional arrays), then you are row-major, assuming that rows are packed sequentially in memory.
The reason is that if xss is an array of arrays, xss[0] is an array, and that array is contiguous in memory; so that is a row; and so xss[1] is the next row; and that is what it means to be row-major.
If you define things differently, you come up with a different answer, unsurprisingly.
verilog15
@verilog15
Jan 17 22:56
Is it possible to define a global variable outside of main (not in another function)?
something like:
let x = 0;
fn main() {

}
verilog15
@verilog15
Jan 17 23:03
Ok I found out that I can use static i: i32 = 0;