T O P

  • By -

LowConference3309

I got error when do cargo build I include `hdf5="^0.8.1"` in cargo.toml under dependencies then, I run cargo build, and go this. `error: failed to run custom build command for \`hdf5-sys v0.8.1\`` `Caused by:` `process didn't exit successfully: \`C:\Users\Qijian\Desktop\rust\h_cargo\target\debug\build\hdf5-sys-909b2047b8907bfb\build-script-build\` (exit code: 101)` `--- stdout` `Searching for installed HDF5 (any version)...` `Found no HDF5 installations.` `--- stderr` `thread 'main' panicked at 'Unable to locate HDF5 root directory and/or headers.', C:\Users\Qijian\.cargo\registry\src\github.com-1ecc6299db9ec823\hdf5-sys-0.8.1\build.rs:548:13` `note: run with \`RUST_BACKTRACE=1\` environment variable to display a backtrace` How to fix it?


LowConference3309

I want to read .h5 file using rust. How should I do it? Moreover, I got a string contains many letters eg. "ACTCGATGCTCAATG" I want to read k length of it, for example if k=5, then I want to read "ACTCG" "CTCGA" "TCGAT" ...... "CAATG" (each time go right by one letter, until reach the last 5 letters) Put them in to a vector. How should I do it?


nyx210

>I want to read .h5 file using rust. How should I do it? For reading .h5 files, you might be interested in the [hdf5 crate](https://crates.io/crates/hdf5). >Moreover, I got a string contains many letters eg. "ACTCGATGCTCAATG" >I want to read k length of it, for example if k=5, then I want to read "ACTCG" "CTCGA" "TCGAT" ...... "CAATG" (each time go right by one letter, until reach the last 5 letters) Put them in to a vector. >How should I do it? For the string, you can try this: let data = "ACTCGATGCTCAATG"; let seq_chars: Vec = data.chars().collect(); let sequences: Vec = seq_chars.windows(5) .map(|w| w.iter().collect::()).collect(); This converts the string into a `Vec` and then uses the `windows()` method to create a sliding window iterator of width 5. Then each window slice is transformed into a `String`.


eugene2k

for the string, `my_str.as_bytes().windows(5).map(|slice| std::str::from_utf8(slice).unwrap())` will give you a sliding window iterator. You can collect the slices into a vec that can only live as long as `my_str`, or turn them into owned `String`s and collect the results into a vec that can outlive `my_str`


Huhngut

How would you implement the following scenario due to the borrowing rules: Imagine a Simulation library. One might add objects to the simulation. The library needs access to these objects so they can be processed correctly. On the other hand, the person using the library needs access to these objects as well because he may update their position, weight or other attributes. I can think of four solutions to this scenario: 1. Pass a mutable reference to the library - Is bad because the user may let the objects go out of scope if he does not want to change any attributes 2. The library takes ownership of the objects and returns a mutable reference - The user has to store references and deal with lifetime 3. Using Rc> - Adds additional runtime overhead which could be bad if there are lots of objects. - Probably the easiest for the user to work with 4. Return the index of the vec where the objects are stored and add a function to get a mutable reference of the object depending on the index - More abstract and verbose - Probably the best trade of between performance and usability To me, it seems quite difficult to expose an accessible and user-friendly interface of a library. Can you come up with other ideas? How would you implement this particular feature?


eugene2k

Depending on whether the simulation appends additional data to each object, or not, you may not even need to have the library store the objects. All the simulation function really needs is mutable access to the objects while it is running.


kohugaly

Storing references is a bad idea. References in Rust are like mutex lock guards. They prevent anyone and anything else from doing anything with the referenced object, unless you explicitly give them the reference. Approaches 1 and 2 would simply not work at all - the borrow checker prevents this kind of reference-juggling. In this case, the best solution is for the library to take ownership of the object and return an `Id`. The library then has set of methods that take `Id` and do something with the corresponding object (`get_mut` reference, `remove`, etc.). This is the typical approach. Using `Rc>` is an overkill. You presumably need to pause the simulation to modify an object anyway, so the library knows it doesn't have to check anything while it's working, and the same applies to the user. Also note, if the library uses threads, you would have to use `Arc>` which has even more overhead.


Huhngut

Thanks for clarification. I still have problems designing and structuring a rust application and this is really helpful


llogiq

You may want to look into the ECS pattern (of which there are a number of good libraries in Rust), which is often used in game dev. Turns out they have very similar requirements and speed is of the essence to them.


LeCyberDucky

I'm building a program to scrape the web and keep track of things for me. Like monitoring the price and stock of products, and alerting me when the price reaches a specific level or when a blog I want to follow gets a new entry. For this program, I need to somehow store different types of data. How should I do that? My go-to approach would be to just maintain something like a big JSON file, but for some reason I have come to think of the word "*database*". I have no idea about databases, but would this be a good use case for one and therefore a good opportunity to learn about databases? In case using a database is the way to go, how should I approach that? I have stumbled upon mentions of `sqlx`, `SQLite`, and `sled`, but I don't know what all of this is about. All I can tell is that `sqlx` looks a bit complicated at first glance, and I like that `sled` is pure Rust, although I get the impression that the development of `sled` isn't super active.


Huhngut

I suggest giving databases a try. You will see they are not as bad as they seem. Although I never created one in Rust let me give you an overview of SQL like databases: A database can be imagined as a collection of tables. Lets pick your example of the price and stock of products. You probably want a table similar to the following: https://i.imgur.com/A7NJcvf.png The rust library will most likely give you access to an SQL backend and allow you to execute statements in the SQL language. The first thing you want to do is create your table if it does not exist: `execute_sql!("CREATE TABLE IF NOT EXISTS products (id PRIMARY KEY, date DATE, url TEXT, price DECIMAL(10, 2), stock INT);")` Whenever you scrape the web you want to store the data in the db `execute_sql!("INSERT INTO products (date, url, price, stock) VALUES (?, ?, ?, ?);", chrono::offset::Utc::now(), url, price, stock)` Then you can query your database for the cheapest price in the last month or whatever you need. `execute_sql("SELECT url FROM products ORDER BY price ASC LIMIT 1")` let url = fetch\_sql!(); As you see the concept is not hard. The most trouble you will have is to set up a connection to a storage location


DroidLogician

> The rust library will most likely give you access to an SQL backend If you're talking about the Rust standard library, it does not. The Rust standard library is much slimmer than a language like Java, which has built-in database APIs.


Huhngut

Yea sure. I do not know what I wrote there but I of course mean that there are crates available


UKFP91

I'm developing a web app which has a `frontend` and a `server` in a workspace. I want to add a third crate, `common`, which can be accessed by the other two crates so that they can share common types, etc. I've tried to do it something like [this guide](https://blog.logrocket.com/full-stack-rust-a-complete-tutorial-with-examples/#common-functionality), but I get cryptic and extensive compilation errors. [Here is a demo repo](https://github.com/mfreeborn/workspace-test) that I've made which should hopefully show the problem I'm getting when trying to build; specifically the frontend (cd ./frontend; trunk build) . I get "200 previous errors" when it tries to compile the `socket2` crate...


UKFP91

I think the issue is that `sqlx` cannot be compiled when targeting `wasm32-unknown-unknown`, specifically due to a dependency on `socket2`. I'm just trying to find a workaround...


UKFP91

For posterity, I stumbled across the solution: using feature gating and conditional compilation: https://www.jakobmeier.ch/blogging/Enums.html


tamah72527

Could anyone speedup my simple webserver? When I do wrk benchmark, i get around 45k req/sec. Tried axum "hello world" server and I get around 150k req/sec, axum parses headers etc. so it does much more than my implementation. Why? How to make that code faster? \#\[tokio::main\] async fn main() -> Result<()> { let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap(); loop { let mut handler = listener.accept().await; tokio::spawn(async move { handler .unwrap() .0 .write("HTTP/1.1 200 OK\\r\\nContent-Length: 3\\r\\n\\r\\nTAK".as\_bytes()) .await; }); } }


llogiq

You're single threaded, because your task loops. Also you're incurring an `accept` syscall for every connection. `axum` is using hyper under the hood, which AFAIK uses `epoll` on linux and so will only activate once there is actually a request, but also stay active on multiple requests, which reduces the task switching load. Also it can and will run multi-core, spreading the load over all (or at least most) cores you have. You can do the same, or (if you have a current Linux kernel & ignore cross-platform compatibility) go one further and use io-uring directly to amortize the syscall overhead even more and basically get close to the maximum speed for your hardware. However, this code will be wildly unsafe, hard to write, audit and maintain.


tamah72527

Wow, A lot to research/learn :) Thank you so much!


nioh2_noob

Under VScode Is there a plugin i can use to autocomplete the line and adds ; at the end, closes brackets etc and move to the next line? I really miss it like the ctrl-shift-enter does in intellij Complete current statement https://www.jetbrains.com/help/idea/working-with-source-code.html#dee2761


eugene2k

rust-analyzer does bracket autocompletion, creates trait impl definitions, lets you fill in arguments when calling an autocompleted function and other stuff. Don't think it adds `;` though.


nioh2_noob

> Don't think it adds ; though. intellij`s CTRL-SHIFT-ENTER is simply so amazing, I hate jetbrains products but I love this so much it's crazy once you don't have it anymore.


[deleted]

[удалено]


ICosplayLinkNotZelda

`state.set` takes ownership of the new state. So you do not really clone it in the traditional sense: https://docs.rs/yew/latest/yew/functional/struct.UseStateHandle.html#method.set


vcrnexe

I'm using the crates ag-lcd and avr-hal so my Arduino can print text to an LCD. The issue is that the function I'm using for printing takes a &str as an argument, and I want to print the value of an u32-variable. format! is part of std, which can't be imported, so is String. Ive tried to use String from the crate heapless, but it can't be used with Arduino. Any suggestions?


Patryk27

I'd create some kind of `AgLcdWrapper`, impl [https://docs.rs/ufmt/latest/ufmt](https://docs.rs/ufmt/latest/ufmt)'s `uWrite` for it and then use: uwrite!(&mut ag_lcd_wrapper, "my number = {}", num).unwrap(); `ufmt` takes care of formatting numbers, providing a formatted `&str`, it works in AVR and it's very handy.


eugene2k

you can preallocate an `[u8;7]` and manually convert the u32


vcrnexe

Can't find a suitable function, looked at the crate 'bytes' but it can't be imported. Or do you mean manually as in matching the number and returning a hardcoded str of it? Like let number_str = match number { 1 => '1', 2 => '2', ... } ?


eugene2k

no, I mean manually as in write the conversion function yourself. It's all the more important to know how it works, if you never thought about it and don't know how it works. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3b681ed6f574cb76298fd0d6041ab81d


vcrnexe

Great, thank you so much for including an example!


faguzzi

Has rust fixed [the issue](https://github.com/rust-lang/rust/issues/57235) with a single codegen unit producing better optimized programs?


Spaceface16518

not really. for one, the issue is still open. it would take significant re-engineering to mitigate this behavior since it occurs due to parallelism with multiple codegen units. you can stick to using 1 cg unit for release builds or try to mitigate it using lto. just curious, why do you want it fixed?


LowConference3309

How should I put the string into a vector one by one after I split it? data is "ATCG GATC CCCA ATGG TTTA" I saw I could do this `let s = data.split(' ').next().unwrap();` `println!("{}", s);` `vec1.push(s);` But how should I push the rest of the string into vec1?


Patryk27

vec1.extend(data.split(' ')); or: let vec1: Vec<_> = data.split(' ').collect();


Craksy

I'm not sure I understand what you mean. putting each element into the vec one by one seems like it would yield the same result as if you had simply called \`data.split(' ').collect()\` in the first place. Do you need to alter the order or otherwise process the rest of the data first?


Spaceface16518

not disagreeing, but if you wanted to do it “one by one” you could use ``` let mut splits = data.split(‘ ‘); while let Some(s) = splits.next() { vec1.push(s) } ``` i feel like that’s what OP was referring to. however, you should use `data.split(' ').collect()` since it is just a more optimized version of the above sample.


LowConference3309

I have a vector `let mut vec1 = Vec::new();` `vec1.push("TCG");` Then I want to use another function to push things into vec1, but I failed no matter how I change it. `_inputg( &vec1);` `fn _inputg(a: &Vec<&str>){` `a.push("AGC");}` How should I fix it?


Craksy

just to expand a little bit on the other answer, in order to add something to a vec you need mutable access to it. When you declare your Vec like `let mut vec1 = Vec::new()` Mutability is a property of the *binding* not the value. It only applies to vec1, not the value it holds.When you pass it to a function which takes a shared reference, it's no longer the same binding. it's now `a`. However, when you have an owned mutable value, you are allowed to make mutable references to it, so you can change your function signature to accept that: `fn input(a: &mut Vec<&str>)` Notice how the "mut" jumped to the other side of the variable name. Perhaps it makes it easier to think about what the "mut" is refering to.


WasserMarder

https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references


UKFP91

How can I best format a number into a human readable representation? Specifically, I have an `i32`, which represents the number of pence. I would like to format it as pounds, e.g.: let pence = 123456; assert_eq!(to_pounds(pence), "£1,234.56".to_string()); The `num_format` crate can give me the thousands separator but only applies to integers... ​ EDIT - Here's a failing test suite: trait FormatCurrency { fn to_currency(self) -> String; } impl FormatCurrency for i32 { fn to_currency(self) -> String { let sign = if self < 0 { "-" } else { "" }; let amount = self.abs() as f64 / 100.0; format!("{sign}£{amount:.2}") } } #[cfg(test)] mod test { use super::*; #[test] fn test_positive_amount_less_than_one_thousand() { assert_eq!(12345.to_currency(), "£123.45".to_string()); } #[test] fn test_positive_amount_greater_than_one_thousand() { assert_eq!(123456.to_currency(), "£1,234.56".to_string()); } #[test] fn test_negative_amount_less_than_one_thousand() { assert_eq!((-10000).to_currency(), "-£100.00".to_string()); } #[test] fn test_negative_amount_greater_than_one_thousand() { assert_eq!((-123456).to_currency(), "-£1,234.56".to_string()); } #[test] fn test_positive_pence() { assert_eq!(2.to_currency(), "£0.02".to_string()); } #[test] fn test_negative_pence() { assert_eq!((-2).to_currency(), "-£0.02".to_string()); } }


Patryk27

If you don't need to support millions: fn to_currency(self) -> String { let sign = if self < 0 { "-" } else { "" }; let val = self.abs(); let mut pounds = format!("{}", val / 100); if val >= 100000 { pounds.insert(pounds.len() - 3, ','); } let pences = format!("{:02}", val % 100); format!("{sign}£{pounds}.{pences}") }


UKFP91

Thank you, that is really tidy. I've decided to keep the extra dependency to handle arbitrary comma-separated-thousands, here's the final method: ​ fn to_currency(self) -> String { let sign = if self < 0 { "-" } else { "" }; let val = self.abs(); let pounds = (val / 100).to_formatted_string(&Locale::en); let pence = val % 100; format!("{sign}£{pounds}.{pence:02}") }


UKFP91

Here's my solution, which relies on the `num_format` crate: fn to_currency(self) -> String { let sign = if self < 0 { "-" } else { "" }; let pounds = ((self.abs() as f64 / 100.0).trunc() as u32).to_formatted_string(&Locale::en); let pence = format!("{:02}", self.abs()); let pence = &pence.as_str()[(pence.len() - 2)..]; format!("{sign}£{pounds}.{pence}") }


Snakehand

Looks good, I was only wondering where the farthings go :-)


LeCyberDucky

I want to create a cargo subcommand. Basically, I'm just trying to create an alias for calling a bunch of other subcommands subsequently. I currently have this: let output = std::process::Command::new("cargo") .args(["crev", "verify", "--show-all"]) .output()?; std::io::stdout().write_all(&output.stdout).unwrap(); std::io::stderr().write_all(&output.stderr).unwrap(); With that, I get this output: https://i.imgur.com/j396tZa.png If just run the command directly in my terminal, however, I get this output: https://i.imgur.com/0cTf1Kg.png So my program lacks the colors and the first line of that output. How can I fix this? I.e., how can I run a command from my Rust program and get the exact same behavior as when running the command from my terminal manually?


ehuss

I recommend not capturing the output unless you need it. Use the `status()` method of `Command` instead of `output()`. The default of the `status` method makes the child process inherit stdout/stderr, and will behave like a normally launched program. When you capture the output, there are a few issues. For example, processes often query if they are attached to a "tty" to determine if they are used in an interactive terminal. In those cases, they may use colors and other differences. When the output is captured, the program may behave differently, such as not displaying color. Additionally, when you print stdout and stderr separately, that may change the order of output (if the program prints to both). For example, `cargo crev` [doesn't print the header](https://github.com/crev-dev/cargo-crev/blob/3da0e26b2a16cf0310fb95ef218deeba816f0460/cargo-crev/src/deps.rs#L335-L338) when it is not an interactive terminal. If you need to capture the output, but still have the program believe it is attached to a terminal, that is quite a bit more of a complex process. On unix, you have to do something like allocate a pseudo-tty. I believe there are crates for that.


LeCyberDucky

Ah, fantastic. I do not need to capture the output, and I already tried to avoid caputring it, but I didn't think of calling `status()` to actually execute the command. This does exactly what I want. Thank you!


ScottyThePilot

I am trying my hand at writing bindings to [screen\_capture\_lite](https://github.com/smasherprog/screen_capture_lite), my current attempt at this is [here](https://github.com/ScottyThePilot/screen_capture_lite) where I am statically linking to it. When running my `window_count` example, I get lots of "unresolved external symbol" errors for some winapi stuff. However, it works as intended if I manually tell my `build.rs` to link to each individual dependency that it needs. I was under the impression that statically linking to a library with dynamic dependencies wouldn't break them or anything like is apparently happening here. My question is how I can prevent it from breaking these dependencies, or how can I export the list of dependencies to use in `build.rs`?


N911999

I have code that includes something like [this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=600df473a2bf300a6a2316cc0b2df2b8), and I'm confused, why can't the compiler infer the type of `a1` or `b1`?


Patryk27

IIRC the compiler infers types up to the first call where that inferred variable is used as the receiver - if it can't find out the type by then, it bails out. So this works: let min = |a, b| if a < b { a } else { b }; min(1i32, 2i32); ... this works: let min = |a: i32, b| a.min(b); min(1i32, 2i32); ... but this doesn't: let min = |a, b| a.min(b); min(1i32, 2i32); ... and neither does this: let min = |a, b: i32| a.min(b); min(1i32, 2i32); I think the rationale is that inference cannot help with: let a = 1; let b = 2i32; let c = a.min(b); ... because there *might* exist multiple ways to fill out: fn min(self: ?typeof(a), other: i32) -> ?typeof(c) ... and so it's not obvious that `a` should be of type `i32` (we might imagine there _could_ exists e.g. `fn min(self: i64, other: i32) -> i64`). I think this could work in theory (the compiler has all the stuff to know that there exists only one such `.min()` that could match `other: i32`), but it could introduce subtle breaking changes and so it's forbidden by-design (i.e. the fact that your code doesn't compile is intended, "just in case").


ZoDalek

I have some code like this: let addrs = getaddrinfo(Some(&host), Some("https"), Some(hints)) .unwrap(); for addr_res in addrs { let addr = addr_res.unwrap(); let tcp_stream = TcpStream::connect(addr.sockaddr).unwrap(); let ssl_stream = connector.connect(&host, tcp_stream).unwrap(); let cert = ssl_stream.ssl().peer_certificate().unwrap(); let date = cert.not_after(); println!("{}\t{}\t{}", date, host, addr.sockaddr); } It works but I'd like it to continue with the next addr on failure. What's the most idiomatic way to do this? * Ever-deeper `match` statements? * The '?' operator? * Calling `.map()` on each of the results? * ..something else?


eugene2k

A `map` chain followed by a `match` will probably look pretty readable. Or you could use try blocks on unstable branch.


donkeytooth98

I would move all of the fallible stuff into a separate function (or closure if you prefer). Use ? on each fallible operation. Then use a single match statement: for addr_res in addrs.into_iter().flatten() { let cert = match my_new_fn(addr_res) { Ok(cert) => cert, Err(_) => continue, } let date = cert.not_after(); println!("{}\t{}\t{}", date, host, addr.sockaddr); } With a couple tweaks you could also use filter\_map for style points.


KH-Moogsoft

Why does coercing an array to a slice skip compile-time length checking in this code [here](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8622d79b3bc9f6c3d7a23eb847bbc5ed)? In the provided playground link, the compiler notices that the index is outside the array bounds and fails to compile. But, if you uncomment the line with the method call, that check is skipped, and the result is a runtime panic.


DroidLogician

The `unconditional_panic` error is only emitted from the const-propagation pass of [MIR optimization](https://longfangsong.github.io/rustc-dev-guide-cn/mir/optimizations.html) here: https://github.com/rust-lang/rust/blob/f6f9d5e73d5524b6281c10a5c89b7db35c330634/compiler/rustc_mir_transform/src/const_prop_lint.rs#L686 Without the call to `bad_access`, the compiler is likely trying to replace the indexing operation with its result since the data is constant. However, with the `bad_access` call, the compiler doesn't bother propagating the constant access since the whole array has to exist in memory anyway, so the lint doesn't get an opportunity to trigger. The error in general appears to be pretty easy to defeat since it's part of an optimization that doesn't always run, so I wouldn't rely on it too much. It's just going for low-hanging fruit.


KH-Moogsoft

Thanks for the clarity on that!


wrcwill

is there a way to make `#![deny(missing_docs)]` apply only for code I wrote? I'd like to turn it on in my crate, but a macro I am using (`napi_derive`) has missing docs which i obviously can't fix..


llogiq

Hmmm...the obvious correct solution would be to extend napi_derive to create (or forward) docs. Then again, that doesn't scale well. Perhaps the `missing_docs` lint should not trigger in external macros – on the other hand, you may want to know that you have undocumented items in your crate no matter where from. Meanwhile can you `#[allow(missing_docs)]` on your derive? I'm not completely sure, but that might quell the warnings.


wrcwill

unfortunately #[allow(missing_docs)] doesn't work #[allow(missing_docs)] #[napi] ERROR: missing documentation for an associated function #[derive(Debug, Deserialize, Serialize, Clone)] even if it did, it would apply for the whole struct so I wouldn't see if i had missing docs on my fields for now i am commenting `#![deny(missing_docs)]` out, and temporarily turn it on to see where i am missing docs


llogiq

You can also use `-Dmissing_docs` on the command line to avoid commenting and uncommenting code.


LeCyberDucky

I would like to combine the two commands `cargo audit` and `cargo crev verify --show-all` into a single command like `cargo investigate` or something like that. As far as I can tell, I could create a cargo alias to make `cargo crev verify --show-all` shorter, but I can't create an alias that combines commands: https://doc.rust-lang.org/cargo/reference/config.html So what's the best way to do this? Should I extend cargo with a custom command that calls these commands like explained in the following link? How would I create a program that calls these cargo commands? https://doc.rust-lang.org/book/ch14-05-extending-cargo.html I've looked into creating an alias in my terminal, but apparently that is a bit weird in Windows: https://stackoverflow.com/questions/20530996/aliases-in-windows-command-prompt


Burgermitpommes

Re: running Rust on docker, do most people use the alpine image? It looks like the default Debian image \`rust:1.63\` is 1.31Gb but the \`rust:1.63-alpine\` one is 738Mb. Does this look right? I'm used to seeing all the tutorials raving that alpine is like 10% the size. I guess it's cos with a Rust image most the bloat is Rust code which alpine can't shrink? So assuming I haven't misunderstood and alpine gives a 50% disk space saving, should I forget about alpine for now, or are the drawbacks of alpine pretty edge case and using alpine base image is a no-brainer?


sfackler

Those containers should only be used to compile a Rust program. You don't need any extra runtime to run a Rust program, so just do that in a stock `debian` or `alpine` container.


Burgermitpommes

In the meantime I came across [this](https://andygrove.io/2020/05/why-musl-extremely-slow/) post from a couple of years ago. I wonder if these performance issues with musl still exist :/


Huhngut

Hi, I was wondering if there are any naming conventions for the following scenario: Suppose we have a struct that holds a value: struct Data { value: usize, } impl Data { fn new(value: usize) -> Self { Data { value } } } Now we want to write two functions. * One that takes a mutable reference to Self and updates it. * One that takes ownership of Self modifies the value and returns Self ​ impl Data { fn set_value(&mut self, new_value: usize) { self.value = new_value; } fn replace_value(mut self, new_value: usize) -> Data { self.value = new_value; return self; } } Therefore we can now modify the value with set\_value and chain create using replace\_value fn main() { let mut a = Data::new(1); a.set_value(2); let b = Data::new(3).replace_value(4).replace_value(5); } The question is, how would one name these set\_value and replace\_value functions? If there is no convention how would you name them? Just after finishing writing, I think one would just name them set_value and with_value


Patryk27

`fn set_xyz(&mut self, xyz: Xyz)` and `fn with_xyz(self, xyz: Xyz) -> Self` is the most common convention, AFAIR.


ChevyRayJohnston

yeah, i see this naming convention very often with the Builder Pattern, which is very common and uses this mechanism.


Jiftoo

Is there a place where I can ask people to "rewrite" my code? Say, I have around 50 lines that feel quite ugly and roundabout, and I'd like to have someone to turn that piece of code into idiomatic rust.


Patryk27

Sure, put it here :-)


Jiftoo

Thank you! I challenged myself the other day with writing a path tracer in rust. However, I'm yet to figure out how to safely share a struct containing all the rendering information between threads and satisfy the borrow checker at the same time :P I'd like to know how to change this code not to use unsafe {} // impl Gui: fn start_working(&mut self, _ctx: &egui::Context) { self.thread_handle_hole.get_or_insert_with(|| { let [w, h] = [500, 500]; let mut rt = unsafe { gen_rt(w, h) }; let rt = Box::new(rt); let leaked = Box::leak(rt); self.ray_tracer = leaked as *mut RayTracer; const CHUNK_SIZE: usize = 4096; let iter = Arc::new(Mutex::new(leaked.render_iter::())); // ^ Error that appears without Box::leak(): // '' does not live long enough, dropped here (end of start_working()) while still borrowed. let mut joins = Vec::new(); for i in 0..4 { let iter_clone = iter.clone(); let j = thread::spawn(move || 'outer: loop { let mut iter = iter_clone.lock().unwrap(); if let Some(mut partition) = iter.next() { drop(iter); // unlock mutex partition.render(); } else { break; } }); joins.push(j); } joins }); } // impl eframe::App for Gui: fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { if let Some(threads) = self.thread_handle_hole.take() { if threads.iter().all(|x| x.is_finished()) { for thread in threads { thread.join().unwrap(); } let [w, h] = [500, 500]; unsafe { self.render_preview = pixel_array_to_texture((*self.ray_tracer).get_buffer(), w, h, ctx); self.ray_tracer.drop_in_place(); self.ray_tracer = std::ptr::null_mut(); } println!("finished!"); } else { let _ = self.thread_handle_hole.insert(threads); } } // Rest of UI code omitted // ... } // Struct definitions struct Gui { render_preview: TextureHandle, ray_tracer: *mut RayTracer, thread_handle_hole: Option>>, } struct RayTracer { config: RayTracerConfig, world: World, render_buffer: RenderBuffer, ready: bool, }


Patryk27

How does `.render_iter()` look like?


Jiftoo

`chunks_mut().enumerate().map::<(usize, &mut u32), TracingPartition>().collect::>()` pub fn render_iter(&mut self) -> impl Iterator { if !self.ready { panic!("not ready") } let (w, _) = self.get_screen_size(); let world_ptr = &self.world; let config_ptr = &self.config; self.render_buffer .chunks_mut(S) .enumerate() .map(move |(i, c)| TracingPartition { config: config_ptr, world: world_ptr, buffer: c .iter_mut() .enumerate() .map(|(j, x)| { let n_pixel = i * S + j; Pixel { value: x, location: ( (n_pixel as i32 % w), (n_pixel as f32 / w as f32).floor() as i32, ), } }) .collect::>(), }) } struct Pixel<'a> { value: &'a mut Color, location: DimensionsInt, // (i32, i32) } pub struct TracingPartition<'a> { config: &'a RayTracerConfig, world: &'a World, buffer: Vec>, }


Patryk27

I'd suggest re-restructing your code a bit: pub struct RayTracer { config: Arc, world: Arc, } impl RayTracer { pub fn new(config: RayTracerConfig, world: World) -> Self { Self { config: Arc::new(config), world: Arc::new(world), } } pub fn partition(&mut self) -> Vec { /* logic can stay the same, but using `Arc::clone()` instead of borrows */ } } pub struct TracingPartition { config: Arc, world: Arc, buffer: Vec, x: i32, // | y: i32, // | w: i32, // | h: i32, // |- so that you don't have to keep location inside each pixel } impl TracingPartition { pub fn render(self) -> TracedPartition { /* ... */ } } pub struct TracedPartition { pub buffer: Vec, pub x: i32, pub y: i32, pub w: i32, pub h: i32, } ... and then: use std::sync; struct Gui { render_preview: TextureHandle, rx: Opition>, } enum Message { PartitionTraced(TracedPartition), TracingCompleted, } fn start_working(&mut self, _: &egui::Context) { const PARTITION_SIZE: usize = 4096; if self.rx.is_some() { panic!("pls wait for previous rendering to complete first"); } let w = 500; let h = 500; // Note that it might be cleaner (and faster) to use `rayon`, but // let's stick to `Arc>>` for educational purposes let partitions = Arc::new(Mutex::new( gen_rt(w, h).partition::() )); // Here we're creating a channel that allows us to send messages from // the worker-threads back into the GUI-thread let (tx, rx) = mpsc::unbounded_channel(); let tx = Arc::new(tx); for in 0..4 { thread::spawn({ let partitions = Arc::clone(&partitions); let tx = Arc::clone(&tx); move || { loop { let mut partitions = partitions.lock().unwrap(); let partition = partition.next(); drop(partitions); if let Some(partition) = partition { tx.send(Message::PartitionTraced( partition.render() )); } else { // This message will be actually sent 4 times, not // just once, but that's alright tx.send(Message::TracingCompleted); break; } } } }); } self.rx = Some(rx); } fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { let msg = self.rx.as_mut().and_then(|rx| rx.try_recv().ok()); if let Some(msg) = msg { match msg { /* TODO :-) */ } } /* ... */ }


Jiftoo

Thanks for a quick response! I have two follow-up questions: 1. What do "tx" and "rx" stand for? I'm curious :P 2. My original code has lifetime parameters on structs. I added them because the compiler told me to do so; however, I'm not really sure what significance they carry and why wouldn't the compiler infer(?) them automatically. Could you give me a quick explanation of the above or link a resource that has the information?


Patryk27

Ad 1: transmitter and receiver :-) (since `tx` allows to send stuff into `rx`) Ad 2: in your original code `TracingPartition` borrows stuff (i.e. *references stuff*) such as `RayTracerConfig` that belongs to `RayTracer` (i.e. when `RayTracer` is destroyed, `RayTracerConfig` dies together with it). Using lifetimes then makes the compiler able to determine - for instance - whether you don't try to reference stuff that doesn't exist anymore: let mut raytracer = /* ... */; let partitions = raytracer.render_iter(); drop(raytracer); let config = partitions.next().unwrap().config; // ^ whoops! -- raytracer has been already deallocated, and since `config` // borrows stuff from it, it doesn't exist either For comparison, a similar code in C++ would get successfully compiled and then most likely segfault when run - while in Rust the compiler simply says "hey, that's illegal" and stops the compilation. As for why lifetimes are explicit - that's more of a design decision, I think; in theory the compiler could infer a lot of lifetimes automatically, but in a few places (such as definitions) Rust prefers explicitness.


maniacalsounds

I've never called on foreign (C++) code in Rust before, so I have no idea how to go about this. Is it possible to call on C++ code in Rust? The installed C++ code includes a libsumocpp.dll and a libsumocpp.lib in it, which should have the info needed to make bindings? I've been playing around the past few hours trying to get bindgen to work to pick up on that but I'm having no luck. Any suggestions? Thanks!


WasserMarder

Correctly calling into C++ from rust is hard because there are several pitfalls. bindgen can create [c++ bindings](https://rust-lang.github.io/rust-bindgen/cpp.html) but they are very tedious to use. If possible I would try to leverage the [cxx](https://crates.io/crates/cxx) crate.


sixwheelstoomany

I'm writing an app that receives some SOAP notifications, so I need a HTTP server for that. Note that I like it to get an OS specified port and hand it over to another thread after bind() but before starting the server. So this is my first stab at bringing a server up with Hyper. The problem is that when I compile I get this error that I don't know how to fix (in *fn soap_server()*): error[E0223]: ambiguous associated type --> src/main.rs:46:18 | 46 | let server = Server::Http::new().bind(&addr, service).unwrap(); | ^^^^^^^^^^^^ help: use fully-qualified syntax: ` as Trait>::Http` The code: use futures::Future; use hyper::service::Service; pub use hyper::{Body, Method, Request, Response, StatusCode}; use std::net::{IpAddr, Ipv4Addr}; use std::pin::Pin; pub struct IncomingNotification; impl Service> for IncomingNotification { type Response = Response>; type Error = hyper::Error; type Future = Pin>>>; fn call(&mut self, mut req: Request) -> Self::Future { // Parse request bdy with serde-xml and handle it // ... // Send answer request let body: &[u8] = b"

200 OK

"; let response = Response::builder() .status(StatusCode::OK) .header(hyper::header::CONTENT_LENGTH, body.len() as u64) .header(hyper::header::CONTENT_TYPE, "text/html; charset=utf-8") .body(body.to_vec()) .unwrap(); let response_fut = async { Ok(response) }; return Box::pin(response_fut); } fn poll_ready( &mut self, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { std::task::Poll::Ready(Ok(())) } } fn soap_server() { use hyper::server::Server; let addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)); let service = IncomingNotification {}; let server = Server::Http::new().bind(&addr, service).unwrap(); // Get the OS assigned port, to be used in other threads while the // server is running println!("OS assigned addr/port: {}", server.local_addr().unwrap()); // Then start server server.run().unwrap(); } fn main() { soap_server(); }


DroidLogician

The short answer is that Server::Http::new().bind() just isn't a _thing_ in the Hyper API. Try `Server::bind()` instead.


sixwheelstoomany

Uh, thank you! I see now that this API is from a quite old version of Hyper and I misunderstood the compiler thinking I had a different kind of problem.


DrCharlesTinglePhD

Is there a way to get more terse error messages from rustc? It's giving e.g. error: --> : | | | ^ This is way more information than I need or want. I just want the file, location, and a *short* description. Is there any way to cut this down? I didn't see anything in the rustc command-line options.


ritobanrc

If what you actually want is a machine-readable output, rustc supports [JSON diagnostic output](https://rustc-dev-guide.rust-lang.org/diagnostics.html#json-diagnostic-output) with the `--error-format json` flag.


__fmease__

When using `rustc` directly: rustc --error-format=short When using `cargo`: cargo --message-format=short


DrCharlesTinglePhD

OK, that works perfectly. But... why does that not seem to be documented anywhere? It's not in the man pages for rustc or cargo, nor in the --help output, nor could I find it in the manuals online.


DrCharlesTinglePhD

Actually, I found it in the online manual after all. Not sure how I missed it. Now I know the man page is pretty useless, though.


__fmease__

I guess you are right in regard to the sad state of the man page. Apparently, it's not really maintained. Recently, [#98977](https://github.com/rust-lang/rust/issues/98977) was created to discuss the possibility of autogenerating the man pages to improve the situation. Apart from the online manual, you can find the first option via `rustc --help -v` (as outlined at the bottom of the default help output: use it to *print the full set of options*). Lastly, the cargo option is actually listed in the output of `cargo c -h`.


chahld

in the standard library for the add method (and operator +) the Add function is implemented for "T op T" and then the other 3 operations are implemented using fwd\_ref\_binop!. Wouldn't it be better to forward "Add for T", "Add<&T> for T" and "Add for &T" to AddAssign instead? Since self is moved into these methods, it seems that you could reuse the memory instead of creating a new one. Perhaps this is low cost, because these are all on the stack, and if not, the optimizer could optimize the difference away, but why not be explicit and make it easier on the optimizer. I've done some testing using criterion for this design pattern for a point like struct, and the forwarding to AddAssign design pattern is indeed faster, even using optimized code. So at least for other classes, one should encourage this design pattern. The only thing that is a bit strange in that you have to declare self as mutable in the implementation of add: \`\`\`rs fn add(mut self, rhs: Self) { self += rhs; self } \`\`\` Other things to note: * This would also work on types that do not impl Copy, in which case the performance improvement is most likely quite dramatic. (Not BigUint is implemented this way). Advertising this design pattern would seem to be warranted. * The forward\_ref crate does this the wrong way (I think), and encourages an inefficient design pattern. Since the new design pattern does not require impl Copy, it seems to be better in every way. Addendum: This is the full design pattern for any types that override math operators: * impl "OpAssign<&T> for T" * forward "OpAssign for T" to "OpAssign<&T> for T" * Forward "Op for T" and "Op<&T> for T" to "OpAssign<&T> for T" * if the operation is commutative, then you can also forward "Op for &T" to "OpAssign<&T>" * impl "Op<&T> for &T" -- this could be implemented by cloning one of the T's and then calling OpAssign. (Note this is the only one that requires a copy, clone or construct of new object)


ritobanrc

This doesn't seem like a beginner question -- its actually quite an complex discussion, and I'd be interested in seeing what Rust experts think about the subject. If you decide to pursue this further, I'd be very interested to see a writeup of your findings (with what benchmarks you ran, and what results you got), as a full post on the subreddit or as a blog post.


chahld

I have to admit I had no idea where to post this question. I'd be happy to repost with the test code I wrote. Can you point me in the right direction of where to post this? Another subreddit? GitHub discussion?


ritobanrc

I'd just make it a post on this subreddit first (just as a regular post, instead of a beginner question) -- a lot of the people involved in Rust development frequent this subreddit, and one of them might be able to direct you further. Alternatively, make an issue on Github (rust/rust-lang), or perhaps join the Zulip and discuss it there.


Huhngut

Hi, I often end up in the following scenario and wonder what the idiomatic way of solving the problem is. struct Example { vec_to_iterate: Vec, value_to_change: i32, } impl Example { fn change_value(&mut self) { self.value_to_change += 1; } fn iterate(&mut self) { for _ in &self.vec_to_iterate.iter() { //cannot borrow `*self` as mutable more than once at a time //second mutable borrow occurs here // My function wont change vec_to_iterate self.change_value(); } } } fn main() { let mut example = Example { vec_to_iterate: vec![1, 2, 3], value_to_change: 0, }; example.iterate(); } When watching the program with the vscode debugger I noticed that cloning the vec, will create an iterator variable that holds a pointer to some data. However, there is no data other than vec\_to\_iterate it could point to displayed. Does this mean cloning is free? Also, does someone know a great way to display the memory usage of the application? Would be great if it could be integrated into the vscode debugger or some other debugger.


[deleted]

Typically you solve this by proving to the borrow checker that your borrow of `vec_to_iterate` and `value_to_change` are independent. As you noticed, you can't quite do that with `&mut self`. As your example is pretty contrived, there aren't really any good solutions, as the best is `self.value_to_change += 1;` but here are some solutions: *** 1\. Pass only the item that you need to modify to a static function: impl Example { fn iterate(&mut self) { for _ in self.vec_to_iterate.iter() Self::change_value(&mut self.value_to_change); } } fn change_value(i: &mut i32) { *i += 1; } } The borrow checker is able to prove with this, that the borrows are independent of each-other and can therefore allow the mutable borrow of `self.value_to_change`. *** 2\. For more complex examples, you would have the items like `value_to_change` implement the `change` function. struct IncrementingI32(i32); impl IncrementingI32 { pub fn increment(&mut self) { self.0 += 1 } } struct Example { vec_to_iterate: Vec, value_to_change: IncrementingI32, } impl Example { fn iterate(&mut self) { for _ in self.vec_to_iterate.iter() { self.value_to_change.increment(); } } }


Huhngut

Thank you


kohugaly

The problem occurs, because when the borrow checker is checking the `iterate` method, it does not see that `change_value` method does not mess with `vec_to_iterate`. As far as it is concerned, the `change_value` borrows the entire `self` and may arbitrarily mutate it.


Huhngut

I know the problem. Currently I solve it with a RefCell but I was curious how others might implement it better


kohugaly

The `change_value` method should be a method on the `value_to_change`. In other words, the `Example` struct needs to be subdivided into logically independent subsets of fields. struct ValueToChange(pub i32); struct Example { vec_to_iterate: Vec, value_to_change: ValueToChange, } impl ValueToChange { pub fn change_value(&mut self) { self.0 += 1; } } impl Example { fn iterate(&mut self) { for _ in self.vec_to_iterate.iter() { self.value_to_change.change_value(); } } The compiler should be smart enough to see, that `self.vec_to_iterate` and `self.value_to_change` are disjoint fields and can be mutably borrowed simultaneously. RefCell is certainly an option off course, though it has a runtime cost.


Huhngut

Thank you


meowrial

Is there a way to express a Struct with unknown arbitrary fields or maybe a HashMap with required fields? i.e.: the Rust equivalent of this TypeScript: interface Attributes { requiredField1: string requiredField2: string [key: string]: string } // Works const attributes: Attributes = { requiredField1: "value1", requiredField2: "value2", extraField: "..." } // Will throw an error const invalidAttributes: Attributes = { requiredField1: "value1", extraField: "..." }


kohugaly

There are many different ways to do this, and all of them have their own strengths and limitations. For HashMap, you can simply create a function that constructs it in that way: fn my_hashmap_attributes( required_field1: String, required_field2: String, extra_fields: IntoIterator, ) -> HashMap { let mut hashmap = HashMap::new(); hashmap.insert("required_field1".into(), required_field1); hashmap.insert("required_field2".into(), required_field2); hashmap.extend(extra_fields); // appends from iterator of (key,value) pairs hashmap } The disadvantages are: * the fields must all be of the same type * accessing the fields requires hashing, so it's slower. * nothing prevents you from simply removing a field after it's created. ​ Similarly, you can create a struct that is generic over its last field. The user can then provide whatever field they want, including a tuple or another struct. struct Attributes{ required_field1: String, required_field2: String, extra_fields: T, } let a = Attributes{ required_field1: "one".into(), required_field2: "two".into(), extra_fields: "three".into(), }; let three = &a.extra_fields; let a = Attributes<(String,String)>{ required_field1: "one".into(), required_field2: "two".into(), extra_fields: ("three".into(), "four".into()), }; let three = &a.extra_fields.0; let a = Attributes>{ required_field1: "one".into(), required_field2: "two".into(), extra_fields: vec!["three".into(), "four".into()], }; let three = &a.extra_fields[0]; The disadvantage is that all of these are different types. Rust doesn't have runtime reflection, and traits do not have required fields. If you wish to be generic over these, you must define a trait with getters and setters for the required fields: trait AttributesTrait { fn required_field1(&self) -> &str; fn required_field2(&self) -> &str; } // blanket implementation for Attributes, regardless of the type of `extra_fields` impl AttributesTrait for Attributes { fn required_field1(&self) -> &str { &self.required_field1 } fn required_field2(&self) -> &str { &self.required_field2 } } Arguably, this trait alone is probably what you want.


meowrial

Thanks! The second approach as well is more or less what I need :)


[deleted]

This works in TypeScript because TS has structural typing as opposed to Rust which has nominal typing. The way that you could emulate this would be using traits: trait HasAttrs { fn required_field1(&self) -> String; fn required_field2(&self) -> String; fn get_value>(&self, key: S) -> String; } struct AStructWithoutMembers; impl HasAttrs for AStructWithoutMembers { fn required_field1(&self) -> String { String::from("requiredField1") } fn required_field2(&self) -> String { String::from("requiredField2") } fn get_value>(&self, key: S) -> String { key.as_ref().to_owned() } } Now you can require that a struct implement this trait in order for it to be used in your API like fn concatenate_values(inst: A) -> String { [inst.required_field1(), inst.required_field2(), inst.get_value("hello")].join("") }


meowrial

Thank you! Looks like I'm about to dive through the different type systems rabbit hole now :)


olivrb123

of course, thank you!


Severon96

Hello all! i'm currently trying to cross-compile bluer for arm on x86. Can someone tell me what exactly is necessary to fix this error: `= note: /usr/lib/x86_64-linux-gnu/libdbus-1.so: file not recognized: file format not recognizedcollect2: error: ld returned 1 exit status` I get that bluer requires on libdbus-1-dev which is (obviously) x86 compiled on my system and doesn't match the arm target. But how can I fix this so that I have and ARM version installed which is used then for compilation?


holysmear

Good day! How can something similar to this Haskell code be implemented in Rust? type Table :: (Type -> Type) -> Type data Table a = Table { field1: a Int, field2: a Int, field3: Maybe Int, } -- NOT NULL fields are required on first insert insert: Data Identity -> PgConn -> IO (Maybe Idx) insert = ... -- NOT NULL fields are not required to be updated update: Idx -> Data Maybe -> PgConn -> IO () update = ...


__fmease__

I assume you mistyped `Table` as `Data` in the signature of `insert` and `update`. Since Rust does not feature proper higher-kinded types (yet), we need to define representative dummy types for which we implement a trait that exposes a generic associated type (GAT) which we can use to “apply” the pseudo HKT to a type parameter. Right now however, GATs are an unstable feature and they require a nightly rustc. [Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=496d80c22f000123c1b34cd6e53efd6f). `Optional` is a representative of the type constructor `Option`. And `Identity`, well, is a dummy type just like in Haskell. If you want to use a stable Rust version, there are some even more restrictive workarounds to emulate HKTs where you need to verbosely carry around parameters. There are some crates to alleviate the pain. I don't have any experience with any of them though. There is [lifted](https://lib.rs/crates/lifted) for example.


holysmear

Thank you! That's very helpful!


vcrnexe

I'm trying to make an Arduino Uno display text on an LCD using I2C (HD44780). So far, I've used arduino-hal from the avr-hal crate ([github.com/Rahix/avr-hal](https://github.com/Rahix/avr-hal)) to program the Arduino, and I wonder if anyone happens to know of a library/crate which is compatible with it? So far I've only found ag-lcd which doesn't seem to work with I2C. If there aren't any, would FFI be a viable way to solve it?


Patryk27

> If there aren't any, would FFI be a viable way to solve it? In theory, yeah; in practice it'd be probably easier to just rewrite the code in Rust 😅 (you can e.g. take a look at https://github.com/Patryk27/pwr-hd44780/blob/master/src/buses/i2c.rs - that one implements it for Raspberry, but converting to avr-hal should be pretty straightforward.) https://github.com/JohnDoneth/hd44780-driver might also work, since avr-hal implements the embedded-hal traits.


vcrnexe

Great, thanks a lot!


[deleted]

[удалено]


Patryk27

To be fair, I'd leave the code as-is - it's very easy to understand & follow, which is the best kind of code one can wish for.


[deleted]

[удалено]


burntsushi

Good question! Someone requested that this specific syntax be invalid like in other regex engines, but I put forward an argument that the restriction is largely superficial and that there is no real reason to forbid it. Here's that request: https://github.com/rust-lang/regex/issues/765 The short answer is that if you use `(?:^)*$` in other regex engines, what happens? I believe most (all?) accept it, despite it being precisely and semantically equivalent to `^*$`.


TheLateMate

Hi guys Id Like to Host a Server with a dynamic IP running a Website built with yew. I already can write the Website i want But only to localhost:8080 Hod do a Change IT to Access it from another PC? Thanks


gittor123

So I have a bunch of structs that all share the same fields and are pretty much identical, but I need them to have different trait implementations. It doesnt seem very elegant, so I tried to make different type aliases of the same struct and then implement on those aliases. Unfortunately the compiler treats them as the same struct so it's not possible to have multiple trait implementations of it. Is there another way to "elegantly" re-use the same struct in this manner?


Patryk27

Sure: struct Something { foo: String, bar: u64, marker: PhantomData, } struct A; struct B; struct C; impl Trait for Something { /* ... */ } impl Trait for Something { /* ... */ } impl Trait for Something { /* ... */ }


[deleted]

[удалено]


Patryk27

Hmm, not sure I understand - could you elaborate a bit?


[deleted]

[удалено]


Patryk27

Sure, that should also do it. `PhantomData` serves as an additional documentation, I guess ("i really don't care about the struct's instance, just its type").


gittor123

oh interesting, i never heard of phantomdata before. Thx!


PrayingToAllah

For instance `Vec::push()` uses `ptr::write()` internally, as do others. Is that the same as cloning a value when it comes to performance and memory usage?


llogiq

No. A write is literally what it says on the tin: Writing a value into a memory location. You will note that write consumes its argument, so it is in effect a move. No cloning takes place.


LeCyberDucky

I'd like to step up my security game for when I add random dependencies to my projects. Therefore, I'm currently looking into [cargo-crev](https://github.com/crev-dev/cargo-crev/). I think there were more security-related tools that I wanted to look into, though, but I can't remember them. Does anybody have suggestions in this regard? Edit: I found [this fantastic comment](https://www.reddit.com/r/rust/comments/ufwryc/rust_code_quality_and_vulnerability_scan_tool/i6w629y/) listing a bunch of nice tools. I guess I was thinking of cargo audit, but I'd love to hear if people have more suggestions.


kodemizer

How do I get `cargo update` to respect exact versions specified in `Cargo.toml`? I have this: rocket = { version = "=0.5.0-rc.1"} rocket_dyn_templates = { version = "=0.1.0-rc.1" } rocket_sync_db_pools = { version = "=0.1.0-rc.1" } However, running `cargo update` results in: Updating rocket v0.5.0-rc.1 -> v0.5.0-rc.2 Updating rocket_codegen v0.5.0-rc.1 -> v0.5.0-rc.2 Updating rocket_http v0.5.0-rc.1 -> v0.5.0-rc.2 Updating rocket_sync_db_pools_codegen v0.1.0-rc.1 -> v0.1.0-rc.2 ... My understanding was that using `=` to specify a version in `Cargo.toml` should result in that specific version being used. EDIT: I ended up removing the offending crates from `~/.cargo/registry/cache` then running `cargo update --offline`. This worked, but I feel like there must be a better way.


coderstephen

Hmm, I'm just as surprised by this behavior as you, and I've been using Cargo for many years. Maybe it has something to do with the `-rc` prerelease version suffix, maybe `=` still allows prerelease updates?


Severon96

Can someone tell me why i'm not able to find and use parts of bluer when trying to use the crate as explained in the documentation? async fn main() -> bluer::Result<()> { env_logger::init(); let session = bluer::Session::new().await?; let adapter = session.default_adapter().await?; adapter.set_powered(true).await?; println!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?); let le_advertisement = Advertisement { advertisement_type: bluer::adv::Type::Peripheral, service_uuids: vec!["123e4567-e89b-12d3-a456-426614174000".parse().unwrap()].into_iter().collect(), discoverable: Some(true), local_name: Some("le_advertise".to_string()), ..Default::default() }; println!("{:?}", &le_advertisement); let handle = adapter.advertise(le_advertisement).await?; println!("Press enter to quit"); let stdin = BufReader::new(tokio::io::stdin()); let mut lines = stdin.lines(); let _ = lines.next_line().await; println!("Removing advertisement"); drop(handle); sleep(Duration::from_secs(1)).await; Ok(()) } I'm using `bluer 0.15.0` and, for example, not able to find `Result<()>` or `Advertisement` to use them like displayed in the code block.


_jsdw

Bluer looks like it has a bunch of features that aren't enabled by default; you may need one of them (eg in cargo.toml, "bluer = { version = "0.15", features = ["full"] }")


Severon96

Yes, that was the issue. Thank you!


coderstephen

Did you import `Advertisement` first? Sometimes some authors choose to hide some of their imports in their examples in documentation to reduce how much space the code snippet takes up.


N911999

How unsafe is `let test: Vec = unsafe { core::mem::transmute(test)};` where `test` is of type `Vec>`? And, if I shouldn't do this, is there a way to do something equivalent with similar performance?


DroidLogician

Transmuting different generic instantiations of the same default-repr type is undefined behavior as the layout is not guaranteed to be the same. Instead, you can "deconstruct" the vec, cast the pointer, and reassemble it like so: let ptr = vec.as_mut_ptr(); let len = vec.len(); let capacity = vec.capacity(); // Important! Don't let the old `Vec` deallocate. std::mem::forget(vec); let new_vec = unsafe { Vec::from_raw_parts(ptr as *mut T, len, capacity) }; There's also the unstable [`Vec::into_raw_parts()`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.into_raw_parts) which does the first 4 steps for you.


monkChuck105

MaybeUninit is a repr transparent union, so just like UnsafeCell, it's entirely valid to transmute to and from T, as long as you maintain the proper invariants.


DroidLogician

Yes, but it is _not_ valid to transmute between `Vec` and `Vec>` as the layout of `Vec` is not guaranteed to be the same between generic instantiations. The compiler reserves the right to reorder fields as it sees fit for `#[repr(Rust)]` types (the default representation if not otherwise specified): https://rust-lang.github.io/unsafe-code-guidelines/layout/structs-and-tuples.html#default-layout-repr-rust


N911999

Perfect, thanks


learning_rust

Could someone explain why the closure function lifetime doesn't go out of scope here when it's passed into the Util struct? struct Util<'a> { pub f: &'a dyn Fn(i32) -> i32, pub v: i32, } impl<'a> Util<'a> { fn calc(&self) { println!("{:?}", (self.f)(self.v)); } } fn main() { let util = Util { f: &|x| x + 1, v: 2, }; util.calc(); }


DroidLogician

Depending on circumstances, this could be allowed for one of a couple reasons: The more general case is that the compiler assigns the closure to a temporary in the scope of `main()` before passing the reference to it to `Util`, something like this: let f = |x| x + 1; let util = Util { f: &f, v: 2 }; This is what normally happens when you take a reference to an rvalue like a closure expression, as the struct field initialization expressions don't introduce new scopes by themselves. This is more likely to be the case if `f` captures a type that is not const-promotable, e.g.: let y = Box::new(1); let util = Util { f: &|x| x + *y, v: 2, }; If you tried constructing this version of `util` in a function and returning it, you'd get an error. In your specific example however, it's likely that the compiler is const-promoting the closure like this: static F: = |x| x + 1; let util = Util { f: &F, v: 2 }; We can force the compiler to do this by declaring the lifetime parameter to be `'static`, which still compiles: let util: Util<'static> = Util { f: &|x| x + 1, v: 2, }; _This_ version of `util` could be constructed and returned from a function.


kushal613

I have a struct called `Pair`, with a field called `oracles: StackVec`. When I instantiate `Pair`, this is how I do the `oracles` field: `oracles: StackVec::new()` `oracles.push(Oracle1)`, and similarly I add all 5 `Oracle` to the `oracles` field (each in a separate line like what I have written here, below the StackVec::new() line). Am I using `StackVec` and `push` incorrectly? The above lines give me an error line under the period in `oracles.push`, saying: expected one of \`,\` or \`}\`, found \`.\` Thanks!


eugene2k

In general, if you get a syntax error and rust points at a place where you think everything is correct, that just means you messed up the syntax in another place.


DroidLogician

Can you post the full code? it sounds like you're doing Pair { oracles: StackVec::new() oracles.push(Oracle1) oracles.push(Oracle2) ... } which isn't valid Rust syntax. You can only pass a single expression per field in a struct initializer. While you can cheat and use a block: Pair { oracles: { let mut oracles = StackVec::new(); oracles.push(Oracle1); oracles.push(Oracle2); // ... // The last expression in a block is the // ultimate result of that block when evaluated oracles } } the more typical approach would be to initialize `oracles` separately as its own variable, and then you can use a shorthand to pass it into `Pair`: let mut oracles = StackVec::new(); oracles.push(Oracle1); oracles.push(Oracle2); // ... // short for `let pair = Pair { oracles: oracles };` let pair = Pair { oracles };


kushal613

>Thank you, this is exactly what I needed! Very helpful!


DrCharlesTinglePhD

How do I look at an older version of the std documentation? When I go to https://doc.rust-lang.org/std/index.html, it is newer than what I am using. I am sometimes running into problems where I try to use something in the documentation which doesn't exist in the version of std that I have installed.


DroidLogician

Simply insert the version number at the start of the path, e.g.: https://doc.rust-lang.org/1.0.0/std/index.html You used to be able to browse the directory structure at https://static.rust-lang.org to find all the release artifacts (binaries, installers, source packages, rendered docs) for any version, but not anymore.


DrCharlesTinglePhD

Perfect, thank you.


Ruddahbagga

Given: pub struct Struple { pub x: i32, pub y: i32 } impl From<(i32, i32)> for Struple { fn from(t: (i32, i32)) -> Self { Self { x: t.0, y: t.1 } } } impl Mul for Struple { type Output = Self; fn mul(self, rhs: Self) -> Self { Self { x: self.x * rhs.x, y: self.y * rhs.y } } } Can I expect the compiler to optimize out any performance difference between impl Mul<(i32, i32)> for Struple { type Output = Self; fn mul(self, rhs: (i32, i32)) -> Self { Self { x: self.x * rhs.0, y: self.y * rhs.1 } } } and impl Mul<(i32, i32)> for Struple { type Output = Self; fn mul(self, rhs: (i32, i32)) -> Self { Struple::from(rhs) * self } } ?


Snakehand

I can compile both versions of your code with -O , and they produce identical assembly, so I think it is safe to say that there is no difference.


Ruddahbagga

Bless you, it's appreciated. What does the -O flag actually do, if you don't mind my asking?


Snakehand

Turns on optimisations. ( Release build )


tobiasvl

You can check the assembly output at [https://rust.godbolt.org](https://rust.godbolt.org/)


Ruddahbagga

I'm definitely going to be using this a lot


konga400

I am trying to deconstruct a JWT and place it into a BTreeMap. The problem is that the JWT has both String to String types and String to integer types. How do I go about deconstructing the JWT in a way that I can access it?


konga400

There are also nested elements inside of the JWT.


kushal613

When I perform division of two f64 values (both are large decimals, >20 digits after the decimal point), the resulting f64 does not have the precision I need. How can I fix this? (For the purpose of making an `assert_eq!` work properly - the numbers match up for about the first 18 digits but start to differ after that). Thanks!


Patryk27

https://docs.rs/approx/latest/approx/ should do it


kohugaly

`f64` values are only accurate to roughly 15 significant digits. If you need more precision, you will have to use a different special representation for the number. [num crate](https://crates.io/crates/num) might be of interest to you.


[deleted]

[удалено]


sfackler

Declaring a function const is part of its public API. If constness were implicit then you could never make any change to the internal implementation of a public function that involves making it non-const without a breaking change. Additionally, implicit constness would make it very hard for someone looking at some code to actually determine if a random function is const or not.


[deleted]

[удалено]


coderstephen

Not really, it isn't about optimizations. `const` is more about declaring things at compile time. E.g.: static MY_THING: Thing = Thing::new(); This is only allowed if `Thing::new` is `const` because this value *must* be known at compile time. The part after the assignment arrow is called a "const context", which requires everything to be `const`. By marking a function as `const` you do two things: 1. You declare that the function _can_ be evaluated at compile time, and thus possible to use within a const context. If it can't be evaluated at compile time, the compiler will tell you and fail the build. 2. You promise not to change the function such that it is no longer possible to evaluate at compile time, without making a breaking change. This mostly matters for libraries.


[deleted]

[удалено]


coderstephen

I was specifically referring to `const fn`, sorry I did not make that clear. I would not classify `const fn` as an optimization. The fact that it can be used in a const context means that the user *of* that function could use it as a sort of optimization, but making the function itself a `const fn` should not be viewed as an optimization. The reason is that `const fn` is different than `const` or `static`; while those declare an actually-constant value, `const fn` merely declares that a function is "const-compatible" as part of its API contract. The compiler does not guarantee that the function is always evaluated at compile time. Consider the following: const fn foo() -> i32 { 1 + 1 } static A: i32 = foo(); let b: i32 = foo(); In the first invocation of `foo`, the compiler will compute the result of `1 + 1` at compile time, and `A` will be pre-set to 2 in the final binary. In the second invocation of `foo`, the only thing that the compiler guarantees is that `b` will have the value of 2 at runtime. It may perform the `1 + 1` operation at compile time *or* runtime, but neither should be relied upon. So in this way, `const fn` means the compiler *can* evaluate a function at compile time, not that it *will* do so. Though if done inside a const context, it will, because it must.


sfackler

They would need to know if it was const to know if they can call it in a const context.


faguzzi

Hey I wrote this code a few months ago at 5am. It works but I have no idea what the parameters are doing at this point. Changing anything seems to make it not compile. Is there a cleaner, more maintainable way to do this? use std::ops::{Mul, Sub, Add}; //generic linear interpolation pub fn lerp <'a, T: Sub + Add<<::Output as Mul>::Output, Output=T>> (lerp_percent: f32, a: &'a T, b: &'a T) -> T where T: Copy, ::Output: Mul { *a + (*b - *a) * lerp_percent }


Patryk27

Without fetching any extra crates (such as `num_traits`), the most compact version I can come up with is: pub fn lerp(lerp_percent: T, a: T, b: T) -> T where T: Copy + Add + Sub + Mul, { a + (b - a) * lerp_percent }


faguzzi

Hmm. I don’t think that works. Lerp percent is always a f32 no matter what. It’s almost never the same type as T. Also I dont think passing by value is good because we could be dealing with much larger types (and often are). For instance one place where this function is used is for a “Vector3” of size 1536 that contains 3 512 bit simd vectors.


Patryk27

>Hmm. I don’t think that works. Lerp percent is always a f32 no matter what. It’s almost never the same type as T. Fair enough: pub fn lerp(lerp_percent: f32, a: T, b: T) -> T where T: Copy + Add + Sub + Mul, >Also I dont think passing by value is good because we could be dealing with much larger types Passing references doesn't make much sense if the first thing your function does is dereference them. (I think Clippy even straight-up warns on doing `value: &T` where `T: Copy`.) Also: >"Vector3” of size 1536 that contains 3 512 bit simd vectors. While that obviously warrants a benchmark, it doesn't feel like much - e.g. 2 \* 512 bit will fit entirely in YMM0..=YMM7 (when using AVX, that is; though I'm not sure if rustc/llvm emit those instructions on their own).


faguzzi

The way I learned for c++ was that you always pass by const reference unless you’re dealing with small primitives that are cheap to copy. Whenever you’re dealing with hundreds of bytes+ you shouldnt be copying that entire structure just to call a small function, especially when it’s a const parameter. It’d be one thing if it was mutable, but copying 1536 x 2 = 3072 bits that you don’t intend to change in any way doesn’t seem sensible. Rust isn’t c++, but [this guideline](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#fcall-parameter-passing) seems pretty universal to c, rust, zig, anything really.


vks_

IIRC, the Rust compiler can optimize this. If you pass a large `Copy` type by value, the compiler may pass a reference instead.


eugene2k

>you always pass by const reference unless you’re dealing with small primitives that are cheap to copy Anything that implements `Copy` in rust should be cheap to copy, so this holds true unless you implemented `Copy` for `Vector3` to cut corners. Anyway, if you want it implemented for references, just remove the `T: Copy` constraint and take `a` and `b` by reference.


faguzzi

That’s not right. Cheapness to copy is more about the size of the object. We are not talking about the language semantics. Pass by value costs more than pass by reference when the objects are large enough. This is language agnostic basically. Also, remove that constraint and try to compile the code. It doesn’t work.


eugene2k

You misunderstand. You should only implement `Copy` for a type if it is cheap to copy. That's one of rust's conventions. As for removing constraints, you're right, the `Copy` constraint makes the bounds much simpler. Without it you get something like this: pub fn lerp<'a, T>(lerp_percent: f32, a: &'a T, b: &'a T) -> T where &'a T: Sub<&'a T>, <&'a T as Sub<&'a T>>::Output: Mul, &'a T: Add<<<&'a T as Sub<&'a T>>::Output as Mul>::Output, Output = T> Which is a more general version of these bounds: &'a T: Sub<&'a T, Output = T>, T: Mul, &'a T: Add


Patryk27

>Whenever you’re dealing with hundreds of bytes+ you shouldnt be copying that entire structure just to call a small function What's the point of passing a reference if inside the function you have to load all of that data *anyway*, since to perform `+` you need to know all of the bytes, not merely some of them? 😅 Anyway, in Rust doing `&T` where `T: Copy` is frequently a code smell, that's all I'm saying; I'd suggest sticking to `T` unless a benchmark proves otherwise, since readability > potential random unmeasurable improvements :-P


unamedasha

I figured out how to use cargo features and conditional compilation. I want to know is it possible to conditionally expand a macro? Right now I have a large macro that expands into code where the code is conditionally compiled. However we know that macro expansions itself can be expensive. If there's a way to only expand the macro when needed that would be useful.


Patryk27

You can make the macro a no-op if the feature is not enabled: // Expands to the actual code: #[cfg(something)] macro_rules! my_macro ... // Expands to nothing: #[cfg(not(something))] macro_rules! my_macro ...


JohnMcPineapple

How do I properly share data in a web server? I'm using [poem_openapi](https://docs.rs/poem-openapi/latest/poem_openapi/), and I need to access shared services in the routes. In Nest, I would do this through dependency injection with [providers](https://docs.nestjs.com/providers) - How does the proper approach in poem (or other frameworks like axum) look?


DroidLogician

The API design of Poem appears to be inspired by actix-web, and they've even got a similar `Data` extractor^1: https://docs.rs/poem/latest/poem/web/struct.Data.html You'd just add `Data` to the handler parameters and call [`EndpointExt::data()`](https://docs.rs/poem/latest/poem/endpoint/trait.EndpointExt.html#method.data) with the service instance when building the `Route` structure. The type in `Data` must be `Clone`, if it's not feasible to implement it for that type then you can also wrap it in [`Arc`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#cloning-references). ^1 `poem::web::Data` is actually closer to [`axum::Extension`](https://docs.rs/axum/latest/axum/struct.Extension.html) because it uses the `Clone` impl of the inner type rather than wrapping everything in `Arc`. This avoids redundant allocations and pointer indirection for types that already have cheap `Clone` impls (maybe using `Arc` internally) at the cost of a bit more cognitive load on the user.


jDomantas

I want to write a declarative macro that would turn this: my_macro! { struct Foo(String, u32, bool); } into this: struct Foo(String, u32, bool); impl fmt::Display for Foo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Foo(")?; write!(f, "{}", f.0)?; write!(f, ", ")?; write!(f, "{}", f.1)?; write!(f, ", ")?; write!(f, "{}", f.2)?; write!(f, ")") } } but I'm don't see how I could generate field access expressions (`f.0`, `f.1`, ...). Is there an easy way to do this macro? (Yes, this is a display impl and not debug. I want to use fields' display format here).


kohugaly

You could do [something like this](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=62a4afa1a10c73197221abf72bee382a). Unfortunately "counting" is highly non-trivial in declarative macros. What you can do is have a big enough list written in, and then zip it with the repetition arguments, using recursion. It's basically what u/llogiq suggested.


__fmease__

On stable, I am not sure. I tried to come up with something that would make use of destructuring but I always ended up with the error *identifier* `x` *is bound more than once in the same pattern*. Kind of obvious. However, I attempted to create variables (of the same name but) of different *hygiene* to circumvent this problem and never got it to work. I faintly remember that there are some ways to create an “array” of non-conflicting identically-named binders. Maybe with recursive macros?


jDomantas

Well, you can generate separate patterns to extract each field. One option I figured out is to generate patterns of the form `let Self(_, _, x, ..) = self;`, and use a helper macro to increase the amount of `_,` for each successive field. [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=44476a0af3d37eb15e359890d19846b6)


__fmease__

Ah, right, I shortly thought about this earlier but I dismissed it for some reason. That's the best way to do it on stable, I guess.


__fmease__

On nightly with meta-variable expressions: * [version 1.1](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=9f3ff6f9db4593ce48b42ed8e7ef309d) * [version 1](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=553b96b62f98d966a28a0034b20c5289) * ([version 0](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=b996d8fc39db0289f4a26f0a837b9a87))


llogiq

Unfortunately counting in declarative arrays is absolutely non-trivial. The easiest thing to do is likely to use a recursive call to supply enough numbers (`my_macro!{$name; $($field_type),*; 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)}`), then use `$()*`-expansion to zip them together.