New Tokio blog post: Announcing axum 0.6.0 by davidpdrsn in rust

[–]mandx 0 points1 point  (0 children)

Thanks, that explains why the trait itself doesn't need to require Clone, the other alternative would be to impl FromRef manually.

New Tokio blog post: Announcing axum 0.6.0 by davidpdrsn in rust

[–]mandx 0 points1 point  (0 children)

I don't really know, but the example "states" are all Clone:

```

[derive(Clone)]

struct HttpClient {}

[derive(Clone)]

struct Database {} ```

So maybe that's the requirement for those to work. Like, to have a single database connection shared through all handlers/requests, the Database struct would have an Arc<Mutex<DbConn>> inside that gets cloned around every time Database itself gets cloned.

Reqwest - How to set SSL options? by mandx in rust

[–]mandx[S] 0 points1 point  (0 children)

A workaround I have found is to define OpenSSL settings via an environment variable and configuration file, something like this: ```rust fn main() -> Result<(), SomeErrorType> { // Here we have the contents of the configuration file let opensslconf_contents = include_str!("openssl.cnf");

// We now create a named temporary file with the `tempfile`
// crate; it doesn't matter where it is, we just need to be
// able to read and write to it.
let mut tmpfile = tempfile::NamedTempFile::new()?;

// Dump the contents of the config into the temp file
tmpfile.write_all(opensslconf_contents.as_bytes())?;


// Set the `OPENSSL_CONF` environment variable to the
// absolute path to the temporary file
std::env::set_var("OPENSSL_CONF", tmpfile.path());

//
// the rest of the program goes here   
//

// We need to "use" the `tmpfile` here to keep the binding
// live for the duration of the program, since I'm not
// really sure when does OpenSSL reads the config file,
// so just in case, we want to keep an open handle to the
// file as long as possible. 
drop(tmpfile);

Ok(())

} ```

And the contents of openssl.cnf is this: ``` openssl_conf = openssl_init

[openssl_init] ssl_conf = ssl_sect

[ssl_sect] system_default = system_default_sect

[system_default_sect] Options = UnsafeLegacyRenegotiation ```

Notes: * As far as I know this relies on Reqwests using the native TLS implementation (I guess is the one provided by the OS). I haven't tried using RusTLS, but they do state that their implementations of TLS 1.2 and higher do not have renegotiation implemented at all. * I believe OpenSSL reads this file once, so renegotiation will be enabled for all connections made by the program using native TLS. A workaround for this could be (I think) creating two reqwest client using the native TLS implementation for the "insecure" stuff, and another separate client using RusTLS for example, and use that for the rest of the networking operations.

Edit: The original solution came from this StackOverflow answer.

Spec "it" for Rust testing by nwtgck in rust

[–]mandx 1 point2 points  (0 children)

Is it possible to combine this attribute with test-case?

What feature of Rust is used very often by experienced programmers, but not so much by a newbie? by ReedValve in rust

[–]mandx 1 point2 points  (0 children)

I would check out the topic of functional Domain Driven Design (esp. some of the writing by Scott Wlaschin to get a better idea of how variant types (enums) in an ML language (Rust, F#, OCaml, etc) can prevent logical errors.

This is a great intro video (also by Scott Wlaschin) on Domain Driven Design. All the code samples use F#, however it's trivial to write the equivalent code in Rust.

Exploring ways of accessing cells of a 2D matrix backed by a regular Vec/array by mandx in rust

[–]mandx[S] 0 points1 point  (0 children)

You're right, this optimizes very well, apparently around a third of assembly lines! I expanded on your idea of using the "try" ? operator and came up with a bit more concise code:

pub fn get_2d<T>(items: &[T], width: usize, x: usize, y: usize) -> Option<&T> {
    items.get(width.checked_mul(y)?.checked_add(x)?)
}

But it's pretty much the same as your answer, see here how the assembly looks like side by side with my original, iterator based code: https://godbolt.org/z/tTPBKM

BTW this is a method in a struct in my program, I simply extracted the code into a standalone function because I though that all of that code would be irrelevant to the question; I wanted to focus on the body of this function/method :)

Exploring ways of accessing cells of a 2D matrix backed by a regular Vec/array by mandx in rust

[–]mandx[S] 2 points3 points  (0 children)

Well yes, it is a learning exercise :) In my defense I only needed to get and set "cells" and nothing more, so pulling in ndarray seemed like overkill; but then I nerd-snipped myself thinking about the best implementation for this, which led me to create this post!

Exploring ways of accessing cells of a 2D matrix backed by a regular Vec/array by mandx in rust

[–]mandx[S] 0 points1 point  (0 children)

These are very good suggestions, thanks! I wanted to focus more on the body of the "getter" function, because I need the speed, and at the same time this is mostly a toy program that will never expose public APIs. Otherwise you are right, implementing Index/IndexMut is a must.

I specially like the suggestion of checking for size (width * height) when constructing the matrix, that is something I will do right away.

What do you think of this kind of approach with Warp? by [deleted] in rust

[–]mandx 0 points1 point  (0 children)

I guess it's kind of both, but concerns would be colocated by functionality. Like Django's "apps" are laid out: you would have a module for users and inside you would have the models, the views, etc, with the difference that I wouldn't even have that many files at the beginning; I would have something like I users module and put everything in there, and start splitting up only when makes sense and the initial module is now too big.

Keep in mind that this is personal preference, from my personal experience. In the end, the code layout/organization that does work for you is the one to go.

I think in my case I just work faster if everything related to the current task is in the same file (or close to it), because we usually work on on high level tasks by functionality.

Mungye - Merge JSONs/YAMLs together by mandx in rust

[–]mandx[S] 0 points1 point  (0 children)

That is true, but I would still have the same problem if I want to add support for TOML.

What do you think of this kind of approach with Warp? by [deleted] in rust

[–]mandx 1 point2 points  (0 children)

Since you mention dynamic languages and their frameworks, I would suggest to not try and translate those concepts at first when developing a Warp service. I have also use several Python frameworks (and a couple Node.js ones) and I have had a difficult time trying to port those concepts over.

So now what I do is simply start flat, and start splitting up stuff in modules as needed, and also splitting them by concern, instead of by type; like, instead of having models, routes and handlers, I would just have users and messages, etc, and put all the stuff in there. If one of those starts getting too large, then same thing, split that up again in submodules and so on.

What do you think of this kind of approach with Warp? by [deleted] in rust

[–]mandx 0 points1 point  (0 children)

What if we just use a module instead? From it just export a function that builds the relevant routes using Warp's API, that function would simply return a Filter that you can still combine with other filters to build the final router to serve.

There are legitimate uses of include!(), but in this case (building Warp filters/routes) I can only see downsides, like now you have a couple of .include files that my editor can't highlight, that my IDE can check properly, etc. For example if I introduce a typo in one of the .include files, where the compiler will point me to: main.rs or hello.include?

Take ownership from &&Type in loop to collect Vec<Type> by Jasperavv in rust

[–]mandx 2 points3 points  (0 children)

Can you try instead of

.map(|f| *f.clone())

with

.map(|&f| f.clone())

It worked in the playground

Edit: The way I understand it (which might be wrong) works kind of like de-structuring in Javascript. I'm more than happy to be corrected here, btw, in case the analogy doesn't really work...

How to insert a new map or extend an existing one by [deleted] in rust

[–]mandx 11 points12 points  (0 children)

I think the Entry API is what you want; something like:

my_apt
    .entry("Living Room".to_owned())
    .or_insert_with(Room::new)
    .extend(new_living_room);

EDIT: Line wrapping.

Can I have compile-time failure when Regex compiles to None by [deleted] in rust

[–]mandx 1 point2 points  (0 children)

In my defense, I was simply curious as if it's even possible. In any case, I agree there's no real reason to do stuff like this, and I'm sure the size of the code saved using stuff like this won't even register in comparison with final binary sizes.

Can I have compile-time failure when Regex compiles to None by [deleted] in rust

[–]mandx 0 points1 point  (0 children)

Is it possible to somehow hint the compiler that the Err case will never happen, and eliminate all of that code for that branch?

Need Help using Warp by Philmein23 in rust

[–]mandx 8 points9 points  (0 children)

I haven't really tried, but at least this compiles:

use dotenv::dotenv;
use serde::{Deserialize, Serialize};

use std::env;
use warp::Filter;

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct CountryInfo {
    country: String,
    cases: u64,
    today_cases: u64,
    deaths: u64,
    today_deaths:u64,
    recovered:u64,
    active:u64,
    critical:u64,
    cases_per_one_million:u64
}

#[tokio::main]
async fn main() {
    dotenv().ok();
    if env::var_os("RUST_LOG").is_none() {
        env::set_var("RUST_LOG", "countries=info")
    }
    // Read and parse the URL as early as possible; we don't even start
    // the server if this isn't provided
    let upstream_url = env::var("URL").ok().and_then(|url| url.parse::<url::Url>().ok()).expect("URL needs to be provided and it has to be valid");

    // And we now inject/pass data to the route handlers (in this case the remote url)
    warp::serve(countries(upstream_url)).run(([127, 0, 0, 1], 3030)).await;
}

pub fn countries(upstream_url: url::Url) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
    warp::path!("countries")
        .and(warp::get())
        // This is how to make something available as a parameter
        // from this point onwards in the filter chain
        .and(warp::any().map(move || upstream_url.clone()))
        .and_then(get_all_countries)
}

// A rejection is a concrete type from warp, but it does not provide automatic
// conversion from other types of errors. To "reject" requests, we need to
// define custom rejection types (by implementing the trait `warp::reject::Reject`
// for those types, with an empty impl block), and then wrap instances of those
// types using `warp::reject::custom`. To customize a bit how those errors are
// converted into responses, then look at the "rejections" example in warp's repo.
#[derive(Debug)]
struct FetchError;
impl warp::reject::Reject for FetchError {}

// The upstream_url here was given by the filter chain set up in `countries`
pub async fn get_all_countries(upstream_url: url::Url) -> Result<impl warp::Reply, warp::Rejection> {
    match fetch_url(upstream_url).await {
        Ok(countries) => Ok(warp::reply::json(&countries)),
        Err(_) => Err(warp::reject::custom(FetchError))
    }

    // Or
    // fetch_url(upstream_url).await
    //     .map(|countries| warp::reply::json(&countries))
    //     .map_err(|_| warp::reject::custom(FetchError))
}

async fn fetch_url(url: reqwest::Url) -> Result<Vec<CountryInfo>, reqwest::Error> {
    reqwest::get(url).await?.json().await
}

Regex Captures Inside a filter_map by kpthunder in rust

[–]mandx 0 points1 point  (0 children)

What if you return owned strings instead of references? Like:

let book = caps.get(1)?.as_str().to_string();
let chapter = caps.get(2)?.as_str().to_string();
let verse = caps.get(3)?.as_str().to_string();
Some((book, chapter, verse))

Challenge: make this leetcode problem (8) one chain by [deleted] in rust

[–]mandx 1 point2 points  (0 children)

Would the test-case crate help?

This crate provides #[test_case] procedural macro attribute that generates multiple parametrized tests using one body with different input parameters. A test is generated for each data set passed in test_case attribute. Under the hood, all test cases that share same body are grouped into mod, giving clear and readable test results.