6 ms·
That does seem a bit painful to me. Maybe it will get better with some Rust macro DSL though...
by ilurkedhere 9y ago
That does seem a bit painful to me. Maybe it will get better with some Rust macro DSL though...
- lewisinc 9y agoWell yeah, that was the point: "While there exist a number of high-level, Flask or Django like frameworks that abstract away most of the fun about this, we will opt for using the slightly lower-level hyper library to handle HTTP..." You should check out Rocket or Actix-Web or Gotham for something a bit more higher-level. Also know that it's Rust we're talking about - it's an expressive languages, but it's also a systems language, if you want something you can toss in a breakpoint and start introspecting or experimenting you'll probably want Ruby or Elixir.
- grayrest 9y ago> That does seem a bit painful to me. It's because it's written using a low level library. Here's the first two sections (the http handling part) in Rocket: #![feature(plugin, custom_derive)] #![plugin(rocket_codegen)] extern crate rocket; use rocket::request::Form; #[derive(FromForm, Debug)] struct NewMessage { username: String, message: String, } #[derive(FromForm, Debug)] struct TimeRange { before: Option<i64>, after: Option<i64>, } #[post("/", data="<message>")] fn message_create(message: Form<NewMessage>) -> String { format!("{:?}", message) } #[get("/?<times>")] fn message_query(times: TimeRange) -> String { format!("{:?}", times) } fn main() { rocket::ignite() .mount("/", routes![message_create, message_query]) .launch(); }
- 2trill2spill 9y agoThat code looks awful, sorry but rust syntax is horrible. I want to like rust but after a couple months of trying I hate the syntax and the over complicated nature of the language.
- always_good 9y agoIt might not be for you. But that's not very damning criticism.
- 2trill2spill 9y agoRust has an overly complicated modules system compared to any other language Ive used. Rust has a million different string types, Can't use inline assembly unless I use a non stable compiler, etc, etc. On paper rust sounds perfect until you use it. edit: And no I'm not talking about the borrow-checker, I like that and it took very little time to figure out.
- steveklabnik 9y agoWe’re simplifying the module system this year, incidentally.
- 2trill2spill 9y agoCool, I'm excited in the results, any timeframe, what are the main ideas?
- steveklabnik 9y agoSo, we wanted to do something more sweeping, but in the RFC discussions, some of the bigger ideas were too controversial, so we had to pare them back. Timeframe: fairly soon. You can already try out most of it on nightly. There's still some final details to work through though. Before we get into details, none of these things are breaking changes; in Rust 2015, we will add lints to nudge you in this direction, in Rust 2018, those will move to deny by default. This means if you truly love the old system, you can still use it, by allowing instead of denying the warnings. Main ideas: * absolute paths begin with the crate name, or "crate" if they're paths in the same crate. One of the core issues that these changes address is that, if you don't develop the right mental model around defining items and use, counter-intuitive results can happen. For example: extern crate futures; mod submodule { // this works! use futures::Future; // so why doesn't this work? fn my_poll() -> futures::Poll { ... } } std is even worse, as you don't even write the `use` or `extern crate` lines: fn main() { // this works let five = std::sync::Arc::new(5); } mod submodle { fn function() { // ... so why doesn't this work let five = std::sync::Arc::new(5); } } Quoting the RFC: > In other words, while there are simple and consistent rules defining the module system, their consequences can feel inconsistent, counterintuitive and mysterious. With the changes, the code looks like this: extern crate futures; mod submodule { use futures::Future; fn my_poll() -> futures::Poll { ... } } fn main() { let five = std::sync::Arc::new(5); } mod submodle { fn function() { let five = std::sync::Arc::new(5); } } Nice and consistent. That being said, there's also some discussion here that hasn't been totally sorted. Using the crate name in this way has some technical problems, and so we might make it that it's "extern::crate_name", so that is mod submodule { use extern::futures::Future; This is a bit verbose though, so we're not sure that's what we want. See the end of this post for that discussion. * "extern crate" goes away. Speaking of the code above, why do we have to write `extern crate futures` anyway? It's already in your Cargo.toml. Cargo already passes --extern futures=/path/to/futures.rlib to rustc. In the end, it just feels like boilerplate. Again, there's that inconsistency between std and futures in the code above. Removing the extern crate line makes it more consistent, and removes boilerplate. 99% of the time, people put the line in the crate root anyway, and half of the 1% who don't get confused when it doesn't work when they do this. * The "crate" keyword can be used like pub(crate) can today, for making something crate-visible but not public externally This feels superficial, but ends up also being a much easier mental model. Here's the problem: you see "pub struct Foo;". Is Foo part of your public API, or not? Only if it's in a public module itself! pub(crate) is longer than just crate, and is often the thing you actually want when you use 'pub' inside something that's not public. So let's encourage the right thing, and one that's easier to tell at a glance. * mod.rs is no longer needed; foo.rs and foo/ work together, rather than foo/mod.rs There's tons of awkwardness here. Most people use foo.rs until they give it a submodule, then they have to move it to foo/mod.rs. This just feels like meaningless change for no reason. Instead of "mod foo; means look in foo.rs or foo/mod.rs", it becomes "mod foo; means foo.rs". Much more straightforward. Same with a "mod bar" inside foo.rs, it becomes foo/bar.rs, (well, as it is today, but you can see how this is more consistent overall. If it had submodules, it might be foo/bar/mod.rs!) Also, if you have a bunch of `mod.rs` files open in your editor, you have no idea what module they corresponds to, as they all say `mod.rs`. Now they'll say the file name instead. ---------------------------- That's the quick summary. I've left out some details. If you want to try this yourself, grab a nightly and add this: #![feature( crate_in_paths, decl_macro, extern_in_paths, crate_visibility_modifier, )] Note this includes the verbose "use extern" stuff. If you'd like to read the details yourself: https://github.com/rust-lang/rfcs/blob/master/text/2126-path-clarity.md https://github.com/rust-lang/rfcs/blob/master/text/2126-path... and https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/ https://internals.rust-lang.org/t/the-great-module-adventure... ; the former is the RFC that was accepted, the latter is the discussion about the extern issue, with a few different variants.
- Rotareti 9y agoThis looks exactly like the Python code I'm currently writing. That's what I would call a Flask-like API. Nice seeing this in Rust! A Python equivalent using the typing module: @app.get("/<times>") def message_query(times: TimeRange) -> str: return format("{:?}", times)
- willglynn 9y agoHow about Actix? From the README at https://github.com/actix/actix-web#example https://github.com/actix/actix-web#example: extern crate actix_web; use actix_web::*; fn index(req: HttpRequest) -> String { format!("Hello {}!", &req.match_info()["name"]) } fn main() { HttpServer::new( || Application::new() .resource("/{name}", |r| r.f(index))) .bind("127.0.0.1:8080").unwrap() .run(); }
- leshow 9y agoAFAIK actix was pretty high in the techempower rankings this year, top 10 or 20 in most.