1
11
submitted 19 hours ago* (last edited 19 hours ago) by raldone01@lemmy.world to c/rust@lemmy.ml

Hello,

I was playing around with rust and wondered if I could use const generics for toggling debug code on and off to avoid any runtime cost while still being able to toggle the DEBUG flag during runtime. I came up with a nifty solution that requires a single dynamic dispatch which many programs have anyways. It works by rewriting the vtable. It's a zero cost bool!

Is this technique worth it?

Probably not.

It's funny though.

Repo: https://github.com/raldone01/runtime_const_generics_rs/tree/v1.0.0

Full source code below:

use std::mem::transmute;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;

use replace_with::replace_with_or_abort;

trait GameObject {
  fn run(&mut self);
  fn set_debug(&mut self, flag: bool) -> &mut dyn GameObject;
}

trait GameObjectBoxExt {
  fn set_debug(self: Box<Self>, flag: bool) -> Box<dyn GameObject>;
}

impl GameObjectBoxExt for dyn GameObject {
  fn set_debug(self: Box<Self>, flag: bool) -> Box<dyn GameObject> {
    unsafe {
      let selv = Box::into_raw(self);
      let selv = (&mut *selv).set_debug(flag);
      return Box::from_raw(selv);
    }
  }
}

static ID_CNT: AtomicU32 = AtomicU32::new(0);

struct Node3D<const DEBUG: bool = false> {
  id: u32,
  cnt: u32,
}

impl Node3D {
  const TYPE_NAME: &str = "Node3D";
  fn new() -> Self {
    let id = ID_CNT.fetch_add(1, Ordering::Relaxed);
    let selv = Self { id, cnt: 0 };
    return selv;
  }
}

impl<const DEBUG: bool> GameObject for Node3D<DEBUG> {
  fn run(&mut self) {
    println!("Hello {} from {}@{}!", self.cnt, Node3D::TYPE_NAME, self.id);
    if DEBUG {
      println!("Debug {} from {}@{}!", self.cnt, Node3D::TYPE_NAME, self.id);
    }
    self.cnt += 1;
  }

  fn set_debug(&mut self, flag: bool) -> &mut dyn GameObject {
    unsafe {
      match flag {
        true => transmute::<_, &mut Node3D<true>>(self) as &mut dyn GameObject,
        false => transmute::<_, &mut Node3D<false>>(self) as &mut dyn GameObject,
      }
    }
  }
}

struct Node2D<const DEBUG: bool = false> {
  id: u32,
  cnt: u32,
}

impl Node2D {
  const TYPE_NAME: &str = "Node2D";
  fn new() -> Self {
    let id = ID_CNT.fetch_add(1, Ordering::Relaxed);
    let selv = Self { id, cnt: 0 };
    return selv;
  }
}

impl<const DEBUG: bool> GameObject for Node2D<DEBUG> {
  fn run(&mut self) {
    println!("Hello {} from {}@{}!", self.cnt, Node2D::TYPE_NAME, self.id);
    if DEBUG {
      println!("Debug {} from {}@{}!", self.cnt, Node2D::TYPE_NAME, self.id);
    }
    self.cnt += 1;
  }

  fn set_debug(&mut self, flag: bool) -> &mut dyn GameObject {
    unsafe {
      match flag {
        true => transmute::<_, &mut Node2D<true>>(self) as &mut dyn GameObject,
        false => transmute::<_, &mut Node2D<false>>(self) as &mut dyn GameObject,
      }
    }
  }
}

fn main() {
  let mut objects = Vec::new();
  for _ in 0..10 {
    objects.push(Box::new(Node3D::new()) as Box<dyn GameObject>);
    objects.push(Box::new(Node2D::new()) as Box<dyn GameObject>);
  }

  for o in 0..3 {
    for (i, object) in objects.iter_mut().enumerate() {
      let debug = (o + i) % 2 == 0;
      replace_with_or_abort(object, |object| object.set_debug(debug));
      object.run();
    }
  }
}

Note:

If anyone gets the following to work without unsafe, maybe by using the replace_with crate I would be very happy:

impl GameObjectBoxExt for dyn GameObject {
  fn set_debug(self: Box<Self>, flag: bool) -> Box<dyn GameObject> {
    unsafe {
      let selv = Box::into_raw(self);
      let selv = (&mut *selv).set_debug(flag);
      return Box::from_raw(selv);
    }
  }

I am curious to hear your thoughts.

2
2
submitted 3 days ago* (last edited 3 days ago) by dontblink@feddit.it to c/rust@lemmy.ml

In python, when you install stuff with pip, it is recommended to use a venv, to avoid breaking dependencies for a program when uninstalling another one, or when two programs need two different versions of the same dependence.

I was wondering if with Rust is the same, or if Cargo manages it all on its own (kind of like apt does), and I shouldn't care about it.

Also since I know Linux kernel is using some Rust, isn't there a risk of breaking my system if I uninstall a program that need some deps that the system itsel needs?

3
1
submitted 5 days ago* (last edited 5 days ago) by thevoidzero@lemmy.world to c/rust@lemmy.ml

TLDR: Searching for person holding professor position to officially act as a committee member on a US PhD defense

Hi all,

I'm in a non CS field. I'm doing PhD in hydrology and I'm good at Geospatial Analysis, data analysis, visualization, modeling and such. I really like programming and have been making open source programs, contributing to open source programs and such. And have been learning rust for last 2 years.

For my PhD dissertation I'm doing a project where I'll be using Rust to make a program with compiled plugin system that can do generalized river related tasks including data analysis and visualization. I have professors in GIS and hydrology to guide those aspects, but I don't have anyone on software side to ask questions, or to look at my work. I tried emailing some people I have seen with open source projects on GIS+rust, but no response.

I'm ideally looking for someone that holds a professor position for my committee who is good with either rust, GIS related algorithms development, and programming languages. However, it woud also be helpful to just have someone woth knowledge about such things. In either scenario, credit and authorship will be given.

I appreciate any response even telling where i could find someone matching the above description. :)

Edit: I can also provide my previous projects in GitHub, websites and such before you decide in messages.

4
1
submitted 1 week ago* (last edited 1 week ago) by gomp@lemmy.ml to c/rust@lemmy.ml

I have two functions that are similar but can fail with different errors:

#[derive(Debug, thiserror::Error)]
enum MyError {
  #[error("error a")]
  MyErrorA,
  #[error("error b")]
  MyErrorB,
  #[error("bad value ({0})")]
  MyErrorCommon(String),
}

fn functionA() -> Result<String, MyError> {
  // can fail with MyErrorA MyErrorCommon
  todo!()
}

fn functionB() -> Result<String, MyError> {
  // can fail with MyErrorB MyErrorCommon
  todo!()
}

Is there an elegant (*) way I can express this?

If I split the error type into two separate types, is there a way to reuse the definition of MyErrorCommon?


(*) by "elegant" I mean something that improves the code - I'm sure one could define a few macros and solve that way, but I don't want to go there

edit: grammar (rust grammar)

5
1
What do you code in Rust? (lemmy.blahaj.zone)

I've only been coding with Python/Javascript since I started my career. I do APIs and websites frontend. I don't really understand what is interesting in learning an other language. For example, I could learn Ruby, but I'd do the same thing I already do.

Rust, C/C++ tho seem to me to be languages to code other things. Hence my question : what do you code? If possible, make distinction between personal projects and professional projects.

6
1
submitted 1 week ago* (last edited 1 week ago) by dontblink@feddit.it to c/rust@lemmy.ml

Let's say I have a struct Event which implements the method permalink:

struct Event {
    base_url: String,
    rel_permalink: String,
    permalink: String,
    title: String,
}

impl Event {
    fn permalink(&self) -> String {
        let permalink = format!("{}{}", self.base_url, self.rel_permalink);
        permalink
    }
}

The method takes 2 fields of the struct and the target would be to return the definition of another field.

Later I instantiate an event1: Event:

let event1 = Event {
                base_url: base_url,
                rel_permalink: rel_permalink.to_string(),
                title: node.value().name().to_string(),
                permalink = permalink(),
            };

Essentially I would like the field permalink to be the value returned by the method permalink, is something like this possible, is this correct? I couldn't find something similar in the docs..

Pheraps using an associated function as constructor would be a better way to handle a similar situation?

Thank you so much!

7
1
8
1
submitted 2 weeks ago by dontblink@feddit.it to c/rust@lemmy.ml
fn get_links(link_nodes: Select) -> Option<String> {

        let mut rel_permalink: Option<String> = for node in link_nodes {
            link = String::from(node.value().attr("href")?);

            return Some(link);
        };

        Some(rel_permalink)
    }

This is what I'm trying to do, and I've been stuck with this code for an hour, I simply don't know how to put this function togheter.. Essentially I would like to take some link_nodes and just return the link String, but I'm stuck in the use of Option with the ? operator.. Pheraps trying to write it with match would clear things out(?)

Also I come from JavaScript in which expressions do not have their own scope, meaning I'm having troubles to understand how to get out a variable from a for loop, should I initialize the rel_permalink variable as the for loop result?

This are the errors i get:

error[E0308]: mismatched types
  --> src/main.rs:55:49
   |
55 |           let mut rel_permalink: Option<String> = for node in link_nodes {
   |  _________________________________________________^
56 | |             link = String::from(node.value().attr("href")?);
57 | |
58 | |             return Some(link);
59 | |         };
   | |_________^ expected `Option<String>`, found `()`
   |
   = note:   expected enum `Option<String>`
           found unit type `()`
note: the function expects a value to always be returned, but loops might run zero times
  --> src/main.rs:55:49
   |
55 |         let mut rel_permalink: Option<String> = for node in link_nodes {
   |                                                 ^^^^^^^^^^^^^^^^^^^^^^ this might have zero elements to iterate on
56 |             link = String::from(node.value().attr("href")?);
   |                                                          - if the loop doesn't execute, this value would never get returned
57 |
58 |             return Some(link);
   |             ----------------- if the loop doesn't execute, this value would never get returned
   = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility
9
1
submitted 2 weeks ago by JRepin@lemmy.ml to c/rust@lemmy.ml

gccrs is a work-in-progress alternative compiler for Rust being developed as part of the GCC project. GCC is a collection of compilers for various programming languages that all share a common compilation framework. You may have heard about gccgo, gfortran, or g++, which are all binaries within that project, the GNU Compiler Collection. The aim of gccrs is to add support for the Rust programming language to that collection, with the goal of having the exact same behavior as rustc.

10
1
CXX-Qt 0.7 release (www.kdab.com)
submitted 3 weeks ago by JRepin@lemmy.ml to c/rust@lemmy.ml

CXX-Qt is a set of Rust crates for creating bidirectional Rust ⇄ C++ bindings with Qt. It supports integrating Rust into C++ applications using CMake or building Rust applications with Cargo. CXX-Qt provides tools for implementing QObject subclasses in Rust that can be used from C++, QML, and JavaScript.

For 0.7, we have stabilized the cxx-qt bridge macro API and there have been many internal refactors to ensure that we have a consistent baseline to support going forward. We encourage developers to reach out if they find any unclear areas or missing features, to help us ensure a roadmap for them, as this may be the final time we can adapt the API. In the next releases, we’re looking towards stabilizing the cxx-qt-build and getting the cxx-qt-lib APIs ready for 1.0.

11
1
submitted 3 weeks ago by aclarke@lemmy.world to c/rust@lemmy.ml

After almost 3 years of work, I've finally managed to get this project stable enough to release an alpha version!

I'm proud to present Managarr - A TUI and CLI for managing your Servarr instances! At the moment, the alpha version only supports Radarr.

Not all features are implemented for the alpha version, like managing quality profiles or quality definitions, etc.

Here's some screenshots of the TUI:

Additionally, you can use it as a CLI for Radarr; For example, to search for a new film:

managarr radarr search-new-movie --query "star wars"

Or you can add a new movie by its TMDB ID:

managarr radarr add movie --tmdb-id 1895 --root-folder-path /nfs/movies --quality-profile-id 1

All features available in the TUI are also available via the CLI.

12
1
submitted 1 month ago by dontblink@feddit.it to c/rust@lemmy.ml

Hi! I'm trying to learn Rust, as a little project, I'm trying to build a web scraper that will scrape some content and rebuild it with a static site generator, or using it for making POST requests.

I'm still at a very early stage and I still don't know much, the simplest error handling strategy I know is using match with Result.

To my eyes, this syntax looks correct, but also looks kind of a lot of lines for a simple http request.

I know the reqwest docs suggest to handle errors with the ? operator, which I don't know yet, therefore I'm just using what I know now.

fn get_document(permalink: String) -> Html {
        let html_content_result = reqwest::blocking::get(&permalink);
        let html_content = match html_content_result {
            Ok(response) => response,
            Err(error) => panic!("There was an error making the request: {:?}", error),
        };

        let html_content_text_result = html_content.text();
        let html_content_text = match html_content_text_result {
            Ok(text) => text,
            Err(error) =>
                panic!(
                    "There was an error getting the html text from the content of response: :{:?}",
                    error
                ),
        };

        let document = Html::parse_document(&html_content_text);

        document
    }

As for my understanding, this is what I'm doing here: I'm making an http request, if i get a Response, I try to get the text out of the response body, otherwise I handle the error by panicking with a custom message. Getting the text out of the request body is another passage that requires error handling, therefore I use the match expression again to get the text out and handle the possible error (In what circumstances can extracting the text of a response body fail?).

Then I can finally parse the document and return it!

I wonder if it is a correct and understandable way of doing what I've in mind.

Do you think this would be a suitable project for someone who is at chapter 7 of the Rust book? I feel like i actually need to build somethiong before keep going with the theory!

13
1
submitted 1 month ago* (last edited 1 month ago) by trymeout@lemmy.world to c/rust@lemmy.ml

I would like to share a bash script I made for when you want to simply run a rust script once and delete it. Instead of having compile the script with rustc, running the binary and then deleting the binary, you can achive all of this with this bash script below.

The first argument will be the rust script file name. The .rs file extension is optional. The rest of the arguments are passed into the executed binary.

Simply name the bash script to something like rust-run.sh.

#!/bin/bash

#Get file path from first parameter
path=$(dirname "$1")

#Get file name from first parameter
fileName=$(basename "$1")
fileName="${fileName%'.rs'}"

#Compile executable and save it in the same directory as the rust script
rustc "${path}/${fileName}.rs" -o "${path}/${fileName}"

#If rustc commands retuned any errors, unable to compile the rust script
if [ $? -ne 0 ]; then
    return
fi

#Execute compilled executable and pass the rest of the parameters into the executable
"${path}/${fileName}" ${*:2}

#Delete compillled executable
rm "${path}/${fileName}"

If someone wants to rewrite this in rust or add these features into the rustc, feel free to do so.

14
1
submitted 1 month ago* (last edited 1 month ago) by nutomic@lemmy.ml to c/rust@lemmy.ml

This release contains numerous bug fixes and minor improvements. Thanks to Kalcifer for reporting many of these.

  • LaTeX formatting is now supported to handle mathematics (thanks Silver-Sorbet)
  • The editor now has a live preview of rendered markdown
  • Better layout for edit history
  • Fixed user links in edit history
  • Edits are now correctly sorted by date
  • Removed maximum width for page
  • Render markdown titles smaller than page title
  • Disable markdown plugins for url shortening and smartquotes
  • Resize article edit input based on length

More details and download

15
1
submitted 2 months ago by gomp@lemmy.ml to c/rust@lemmy.ml

(I'm just starting off with rust, so please be patient)

Is there an idiomatic way of writing the following as a one-liner, somehow informing rustc that it should keep the PathBuf around?

// nevermind the fully-qualified names
// they are there to clarify the code
// (that's what I hope at least)

let dir: std::path::PathBuf = std::env::current_dir().unwrap();
let dir: &std::path::Path   = dir.as_path();

// this won't do:
// let dir = std::env::current_dir().unwrap().as_path();

I do understand why rust complains that "temporary value dropped while borrowed" (I mean, the message says it all), but, since I don't really need the PathBuf for anything else, I was wondering if there's an idiomatic to tell rust that it should extend its life until the end of the code block.

16
1
submitted 2 months ago by tracyspcy@lemmy.ml to c/rust@lemmy.ml

Rust ownership is a fundamental part of the language.

I’ve summarized the basic concepts here as a learning exercise for myself.

I’m sharing this to gather feedback, corrections, and suggestions.

Feel free to offer improvements wherever needed!

17
1
submitted 2 months ago by nutomic@lemmy.ml to c/rust@lemmy.ml

We also have documentation to setup the dev environment: https://join-lemmy.org/docs/contributors/02-local-development.html

If you have questions, feel free to ask here, in the relevant issue or in matrix.

18
1
submitted 2 months ago by nutomic@lemmy.ml to c/rust@lemmy.ml

Which of these code styles do you find preferable?

First option using mut with constructor in the beginning:

  let mut post_form = PostInsertForm::new(
    data.name.trim().to_string(),
    local_user_view.person.id,
    data.community_id,
  );
  post_form.url = url.map(Into::into);
  post_form.body = body;
  post_form.alt_text = data.alt_text.clone();
  post_form.nsfw = data.nsfw;
  post_form.language_id = language_id;

Second option without mut and constructor at the end:

  let post_form = PostInsertForm {
    url: url.map(Into::into),
    body,
    alt_text: data.alt_text.clone(),
    nsfw: data.nsfw,
    language_id,
    ..PostInsertForm::new(
      data.name.trim().to_string(),
      local_user_view.person.id,
      data.community_id,
    )
  };

You can see the full PR here: https://github.com/LemmyNet/lemmy/pull/5037/files

19
1
submitted 3 months ago by tracyspcy@lemmy.ml to c/rust@lemmy.ml
20
1
submitted 3 months ago by me@bassam.social to c/rust@lemmy.ml

Rust Project goals for 2024

https://blog.rust-lang.org/2024/08/12/Project-goals.html

cc: @rust@lemmy.ml

21
1
submitted 3 months ago* (last edited 3 months ago) by brokenix@emacs.ch to c/rust@lemmy.ml

#rust folks it's supposed to throw this error without lazy_static crate , but it doesn't?
https://git.sr.ht/~carnotweat/morning-rust/tree/main/item/sum.rs#L14
cc @rust @learningrustandlemmy

22
1
submitted 3 months ago by thevoidzero@lemmy.world to c/rust@lemmy.ml

cross-posted from: https://lemmy.world/post/18129059

This feels like it should already be a feature in a terminal. But I didn't find anything that let me do this efficiently.

I had a rust library for converting list like 1-4,8-10 into vectors, but thought I'd expand it into a command line command as well, as it is really useful when I want to run batch commands in parallel using templates.

I wanted to share it since it might be a useful simple command for many people.

23
1
submitted 4 months ago* (last edited 4 months ago) by thevoidzero@lemmy.world to c/rust@lemmy.ml

Hi all,

mpv communities seem to be tiny in lemmy, so I'm sharing it here.

This is a program I made for music control from local network.

You can run it in a computer with some local media files, or youtube links or any other links yt-dlp supports. And then with the server, you can control the media player and the playlist from any devices in your local network. So that you can just show a QR code or something to house guests for parties, or have it bookmarked within family to control the music.

I wanted to make something similar to how youtube app let's you play in TV and such, but my skills were not enough to do that. So I tried a simple alternative that works with computers. In an ideal world, I could make "Play with local mpv server" option come while on other android apps, but I have zero experience in android app development and it looks complicated.

I know some other programs also give option to control media, but I wanted to give it a go with a simple implementation. Making the web-server was a tricky part. Only tutorial from the rust book was useful here as every other web server developement in rust seems to be async ones using libraries so I would have to make a complicated system to communicate with the mpv. Using the simple Tcp connection let me make a thread with mpv instance in the scope. I do need to support https and file uploads and other things, but I haven't had any luck finding a solution that works with simple Tcp connection like in the tutorial. Let me know if you know anything.

Github: https://github.com/Atreyagaurav/local-mpv

24
1
submitted 4 months ago by Binette@lemmy.ml to c/rust@lemmy.ml

For context, I am using the libraries bevy and print_typewriter.

I noticed that before the program even starts, I am able to type in characters. This is bad, since when I ask for the user's input, the previous characters are included inside of it.

How do I make sure that only the user's input after the program starts, and after I print a question gets in?

25
1
submitted 4 months ago* (last edited 4 months ago) by runiq@feddit.org to c/rust@lemmy.ml
view more: next ›

Rust Programming

8190 readers
20 users here now

founded 5 years ago
MODERATORS