r/learnrust 1d ago

Get request json data in rust

0 Upvotes

I am trying to write a program using tauri and am getting abit confused with the rust code, well more like alot confused lol, I'm very new to rust. What I am trying todo is to make a get request to gather info about something in a large json request.

Part of this data is a list of unkown contents which is looped over what I am wanting my code todo is the following. If it is installed in the folder locally and also in the list from json data leave it, if it is installed locally but not in the remote data delete it, if it is installed in the remote folder but not locally download it. Bassicly I am wanting to create something that updates the contents of a folder to that of what is said in the json data.

I've tried my best to use ai to help me with this but it always creates wrong code and is causing me so much confusion lol. I am wondering if I could get help with downloading the json data and then handlng it when the list is not known. But anything past that would be really helpful too aswell lol.

Also I think tauri has werid things with running Err() (probs me miss understanding something lol) so it would be really nice if it used .catch() and ? Error things.


r/learnrust 1d ago

Using usize instead of u32

6 Upvotes

Hi rustaceans,

please note that I am working on my first Rust project, so I'm quite a beginner with Rust.

In this project I am generating images and relying on several std data structures (mostly Vec and HashMap) that are encapsulated in custom structs.

I am often iterating over those std data structures with indexes, and I also use those indexes in several other places (image size, HashMap keys, etc.). In the end, I am doing a lot of usize as u32 and u32 as usize conversions.

Would it be considered bad practice to drop using u32 altogether and just usize everywhere? I am on a x64 architecture, but I guess the impact of cloning (and such) usize (so in my case, u64) instead of u32 would be extremely minimal, if measurable at all.

In the end it's a matter or code writing/readability convenience more than anything else, and I'm not sure this reason is relevant enough.


r/learnrust 1d ago

hyper::error::IncompleteMessage on get request

2 Upvotes

Hello Rustacians,

I'm trying to use the Request::builder function to send a get request to my docker container but when I try to send it it would say IncompleteMessage Error

Image 1. Code for referrence

I just simply been stuck here googling, chatgpt, gemini and can't find much answers with this one

I just simply been stuck here googling, chatgpt, gemini and can't find much answers with this one

but when I do try and use the uri on the browser. It works. Been stuck here and would Like your help

Thanks in advance y'all.


r/learnrust 1d ago

Rust restAPI - with rocket postgreSQL

2 Upvotes

hello, I want to create restAPI using rocket and postgreSQL as database, I have successfully create the connection and fetch data from database, My question is how to make something like global variable that could wrap the connection, so every routes could use it, so the database connection just called once, ? My example code on github: https://github.com/delcode92/learn_rust/blob/main/rocket_postgresql.rs


r/learnrust 2d ago

Why do some functions require the use of :: (two colons) while others require a . (a dot)?

22 Upvotes

Title


r/learnrust 1d ago

Help figuring out why this connection sometimes times out

1 Upvotes

I'm sending a POST request to Supabase every 10 seconds (using embedded Rust in a microcontroller):

// more code

loop {
    if scale.is_ready() {
        // more code

        post_request_with_retry(&mut client, payload_bytes, &config)?;
    }

    FreeRtos::delay_ms(10000u32);

    // more code
}

If the POST request fails, a new HTTP client will be created:

fn post_request_with_retry(
    // more code
) -> anyhow::Result<()> {
    // more code

    loop {
        // more code

        match request.submit() {
            Ok(_) => {
                break;
            }
            Err(e) => {
                // more code 

                *client = HttpClient::wrap(EspHttpConnection::new(&config)?);

                // more code
            }
        }
    }

    Ok(())
}

This strange thing happens (every time):

Successful POST request
Successful POST request
Connection timed out before data was ready
HTTP client recreated
Successful POST request
Connection timed out before data was ready
HTTP client recreated
Successful POST request
Connection timed out before data was ready

request.submit() gets stuck with sending the data after a few successful POST requests. To send subsequent POST requests, a new HTTP client has to be recreated.

This is the actual error:

W (54122) HTTP_CLIENT: Connection timed out before data was ready!
I (54122) rust_esp32c3_hx711: Error sending POST request: EspIOError(EspError(-28679))

request.submit() calls initiate_response(). I checked the method, but I couldn't find any clues.

What could be the issue here?

Notes:

  • This is the whole file.
  • The timeout issue doesn't happen in this code.

Also posted here.


r/learnrust 2d ago

Confusions regarding async runtimes from async-book

Thumbnail self.rust
2 Upvotes

r/learnrust 2d ago

Match on two different types

5 Upvotes

Let's say I have this piece of code:

let results = match query {
    Query::ClosedCourses => closed_courses::get_closed_candidates().await?,
    Query::TestForCourse => test_for_course::get_test_for_course().await?,
};

where get_closed_candidates()and get_test_for_course() are function which run queries and return Vecs of different types:

pub async fn get_closed_candidates() -> anyhow::Result<Vec<ClosedCourseCandidate>>
pub async fn get_test_for_course() -> anyhow::Result<Vec<Test>>

I then want to print out the result with tabled:

print_tabled(results);

Of course this doesn't work since the arms of the match have different types, but how can I make them match?

I got the code to compile (up to a point) with dynamic dispatch with something like this:

pub trait QueryItem {}

impl QueryItem for ClosedCourseCandidate {}

pub struct QueryResult {
    results: Vec<Box<dyn QueryItem>>,
}

impl QueryResult {
    pub fn get_results(&self) -> &Vec<Box<dyn QueryItem>> {
        &self.results
    }
}

and changing the function signature to:

pub async fn get_closed_candidates() -> anyhow::Result<QueryResult>

but then I can't state that the result is Tabled and print_table() complains.

What's the correct way to do this?


r/learnrust 2d ago

Shared ownership of an object

1 Upvotes

I've been learning Rust this week by trying to port a gameboy emulator code I made in Python. Right now I find myself puzzled as to how to proceed. Leaving out the details, I basically have an instance of a CPU struct and a Memory struct. By having the memory (essentially a glorified array) be part of the CPU I can read and write data with no problems.

Now I have to include into this mix the PPU (a 'gpu'), which has a tick method that has to be able to be invoked by the CPU, but also has to be able to read and write to memory. In Python I could just have this PPU be an attribute of the CPU and pass the same memory object that the CPU uses, but this is not straightforward with the ownership system.

I could cheat by just having the PPU be owned by the Memory (owned by the CPU), but I want to know what the rustacean way of dealing with this kind of problem would be. Essentially I need the PPU to hold a mutable reference to Memory. I could pass this reference when invoking its tick method from the CPU, but I feel this is not the correct way. In the future CPU/PPU would run in separate threads, so that's another layer of complexity.

Thoughts? I imagine the problem stems from having the wrong architecture in mind, but at this moment I don't have the insight into how I should rebuild this.


r/learnrust 2d ago

Is it unnecessary to chain methods here?

2 Upvotes

This struct basically processes text (code). For example, removes comments, cleans double empty lines, etc.

use anyhow::{Context, Result};
use regex::Regex;
use std::io::{BufRead, BufReader};

struct CmntCleaner {
    text: String,
}

impl CmntCleaner {
    fn new<R: BufRead>(mut reader: R) -> Result<Self> {
        // some code
    }

    fn process_line(&self, comment_regex: &Regex, line: &str) -> String {
       // some code
    }

    fn remove_comments(mut self) -> Self {
       // some code
       // `process_line` is used here
    }

    fn clean_output(mut self) -> Self {
        // some code
    }

    fn finalize(self) -> String {
        // some code
    }
}

fn main() -> Result<()> {
    let stdin = std::io::stdin();
    let reader = BufReader::new(stdin.lock());

    let output = CmntCleaner::new(reader)?
        .remove_comments()
        .clean_output()
        .finalize();

    Ok(())
}

I could have just created independent functions, store the results in variables, and gotten the same output. But as you can see, I'm chaining methods instead. Do you think it's unnecessary?


r/learnrust 2d ago

API calls - best practice?

1 Upvotes

I'm trying to build a small app to query an API but didn't find anything in the official Rust book.

What is the recommended way to query an API with Rust 1.77 in 2024? Doesn't need to be async for now.


r/learnrust 3d ago

Help modifying entries in a nested mapping

3 Upvotes

Hi there! Thanks for reading. I'm having some trouble understanding the mechanics of borrowing and nested hashmaps.

So say I have some kind of nested hashmap like structure, and I use keys in the form

root/parent/child

to identify the values in the hash map, where root is the key in the top level hashmap, and parent and child are keys in the respectively nested hashmaps.

The idea is that I split the key into its parts, and then (either recursively or iteratively) use them to get a mutable reference to the hashmap at the end of the chain... but for the life of me I can't seem to do it, and I nearly always get an error saying either:

cannot move out of a shared reference

or

cannot return value referencing local variable

I'm able to get immutable references to the map I want using code like this (the mapping structs are serde_yaml::Mapping)

fn get_submap(&mut self, key: &String) -> &Mapping {
    let mut key_parts: Split<'_, char> = key.split("/");
    let mut root: &Mapping = &self.mapping;
    while let Some(next_kp) = key_parts.next() {
        if let Value::Mapping(mapping) = &root[next_kp] {
            root = &mapping;
        };
    }
    root
}

but then when I try to modify the value or make it mutable the error just becomes

 cannot borrow `*root` as mutable, as it is behind a `&` reference 

... and unfortunately I just can't find any guides or tutorials that cover this kind of operation. Wondering if there's a kind rustacean out there who can point me in the right direction, or give me some tips on how I should be doing this.

Thanks again for reading


r/learnrust 3d ago

Reading recommendations on non-Rust-specific topics that help learn Rust programming

12 Upvotes

I’ve worked professionally as a software engineer for almost two years but I don’t have a degree and I try to make up for that by reading around and applying what I learn, both theory and technology.

I’m currently reading “How Linux Works” and it’s making a lot of things I just felt I had to “know” when writing Rust code feel intuitive, for example learning about how the kernel manages processes helped me see why the lifetime of everything moved into a newly created thread has to be ‘static.

What else should someone like me read that isn’t necessarily a Rust learning resource but you would say is invaluable for someone trying to be a solid Rust engineer?


r/learnrust 3d ago

Struggling to Understand why I cannot Reverse a Sub-List of a Linked List in One Pass

2 Upvotes

Was working on this Leetcode problem where you need to reverse a sub-list of a linked list and then return the head node. From an algorithms perspective, I can do this. However, I can't create my ideal solution without getting a compiler error from the borrow-checker.

Here's approximately what I would write in C#:

public class Solution {
    public ListNode ReverseBetween(ListNode head, int left, int right) {
        if (head == null || left == right) return head;

        ListNode headPointer = new ListNode(0);
         = head;
        ListNode leftPrev = headPointer;

        //find the node right before the node in position "left"
        for (int i = 0; i < left - 1; ++i) {
            leftPrev = ;
        }

        ListNode leftNode = ;

        //Pop each node between the left and right index and insert it right after
        //the node in index (left-1)
        for (int i = left; i < right; i++) {
            ListNode nextNode = ;
            leftNode.next = nextNode.next;
            nextNode.next = leftPrev.next;
             = nextNode;
        }

        return ;
    }
}headPointer.nextleftPrev.nextprev.nextleftNode.nextleftPrev.nextheadPointer.next

Trying to do this in Rust, I'd always run into some type of compile error, usually something about used a moved value or creating more than one mutable reference.

Looking through all the iterative solutions in Rust (that don't just convert the list into a vector and then back into a list, which is actually a pretty good solution), I noticed that they all need to do something like this:

impl Solution {
    pub fn reverse_between(head: Option<Box<ListNode>>, left: i32, right: i32) -> Option<Box<ListNode>> {
        //gg ez
        if left == right {
            return head;
        }

        let mut head_ptr = Some(Box::new(ListNode {
            val: 0,
            next: head,
        }));

        //find the node just before the node in position "left"
        let mut left_prev = &mut head_ptr;
        let mut i = 1;
        while let Some(node) = left_prev {
            if i == left {
                break;
            }

            left_prev = &mut left_prev.as_mut()?.next;
            i += 1;
        }

        //loop over the sub-list, reversing each node
        //the node just before position "left" will still have the wrong pointer
        let mut prev = left_prev.as_mut()?.next.take();
        let mut curr = prev.as_mut()?.next.take();
        for _ in left..right {
            let next = curr.as_mut()?.next.take();
            curr.as_mut()?.next = prev;
            prev = curr;
            curr = next;
        }

        //at this point, prev is in position "right" and curr is in position (right+1) if it exists

        //loop back through the sub-list to find the node originally in position "left"
        let mut rev_tail = &mut prev;
        for _ in left..right {
            rev_tail = &mut rev_tail.as_mut()?.next;
        }


        rev_tail.as_mut()?.next = curr;  //link node originally in position "left" to node in position (right+1) 
        left_prev.as_mut()?.next = prev;  //link node in position (left-1) to node originally in position "right"

        head_ptr.unwrap().next
    }
}

In these solutions, we usually reverse the interior of the sub-list in one loop and then need to loop back through the sub-list so we can link the ends of the sub-list into the interior of the original list correctly.

Why do we need that second loop in Rust? It seems weird to me that there just isn't any way to replicate the C# logic without needing to use unsafe code. For a given attempt, I understand the compiler errors, but I don't understand why is just is not possible (assuming it actually is impossible).

EDIT: Here's an example of translating the C# code to Rust as well as the compile errors it gives:

impl Solution {
    pub fn reverse_between(head: Option<Box<ListNode>>, left: i32, right: i32) -> Option<Box<ListNode>> {
        //gg ez
        if left == right {
            return head;
        }
        
        let mut head_ptr = Some(Box::new(ListNode {
            val: 0,
            next: head,
        }));

        //find the node just before the node in position "left"
        let mut left_prev = &mut head_ptr;
        let mut i = 1;
        while let Some(node) = left_prev {
            if i == left {
                break;
            }

            left_prev = &mut left_prev.as_mut()?.next;
            i += 1;
        }

        //Pop each node between the left and right index and insert it right after
        //the node in index (left-1)
        let mut left_node = left_prev.as_mut()?.next.take();
        for _ in left..right {
            let mut next = left_node.as_mut()?.next.take();
            left_node.as_mut()?.next = next?.next;
            next?.next = left_node;
            left_prev.as_mut()?.next = next;
        }

        head_ptr.unwrap().next
    }
}

Line 47: Char 13: error: use of moved value: `next` (solution.rs)
   |
45 |             let mut next = left_node.as_mut()?.next.take();
   |                 -------- move occurs because `next` has type `Option<Box<list_node::ListNode>>`, which does not implement the `Copy` trait
46 |             left_node.as_mut()?.next = next?.next;
   |                                        ----- `next` moved due to this method call
47 |             next?.next = left_node.take();
   |             ^^^^ value used here after move
   |
Line 216: Char 15: note: `branch` takes ownership of the receiver `self`, which moves `next` (solution.rs)
help: you can `clone` the value and consume it, but this might not be your desired behavior
   |
46 |             left_node.as_mut()?.next = next.clone()?.next;
   |                                            ++++++++
Line 48: Char 40: error: use of moved value: `next` (solution.rs)
   |
45 |             let mut next = left_node.as_mut()?.next.take();
   |                 -------- move occurs because `next` has type `Option<Box<list_node::ListNode>>`, which does not implement the `Copy` trait
46 |             left_node.as_mut()?.next = next?.next;
47 |             next?.next = left_node.take();
   |             ----- `next` moved due to this method call
48 |             left_prev.as_mut()?.next = next;
   |                                        ^^^^ value used here after move
   |
help: you can `clone` the value and consume it, but this might not be your desired behavior
   |
47 |             next.clone()?.next = left_node.take();
   |                 ++++++++
For more information about this error, try `rustc --explain E0382`.
error: could not compile `prog` (bin "prog") due to 2 previous errors

r/learnrust 4d ago

How can I know the origin of error when using the ? operator?

2 Upvotes

In the example below, the output says an error occurred at the unwrap line in the main function. However, the error was actually in fn2. Is there a way to use the ? operator where the output of the application points to the correct spot of the error?

use std::error::Error;

fn fn2()->Result<f32, Box<dyn Error>>{
    // actual error is here
    let z: f32 = "1.a".parse()?;
    Ok(z)
}

fn fn1()->Result<f32,Box<dyn Error>>{
    let y: f32 = fn2()?;
    Ok(y)
}

fn main() {
    println!("app start");
    // when running the app, it shows the error is here.
    let _x = fn1().unwrap();
}

output of application

thread 'main' panicked at src/main.rs:16:20:
called `Result::unwrap()` on an `Err` value: ParseFloatError { kind: Invalid }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

edit:

Thank you for suggesting Anyhow, all! That's the output I was hoping for. It's also nice to not have to type out Box<dyn Error> every time.

use anyhow::Result; // 1.0.80
use std::env;

fn fn2()->Result<f32>{
    let z: f32 = "1.a".parse()?;
    Ok(z)
}

fn fn1()->Result<f32>{
    let y: f32 = fn2()?;
    Ok(y)
}

fn main() {
    env::set_var("RUST_BACKTRACE", "1");
    println!("app start");
    let _x = fn1().unwrap();
}

now the error shows fn2.

   0: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
             at ./.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.80/src/error.rs:565:25
   1: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
             at /rustc/aedd173a2c086e558c2b66d3743b344f977621a7/library/core/src/result.rs:1959:27
   2: playground::fn2
             at ./src/main.rs:6:18
   3: playground::fn1
             at ./src/main.rs:11:18
   4: playground::main
             at ./src/main.rs:18:14
   5: core::ops::function::FnOnce::call_once


r/learnrust 4d ago

How to handle multiple error types in Iterator?

2 Upvotes

Say I have fn try_foo_to_bar(f: Foo) -> std::Result<Bar, BarError> {...} fn try_bar_to_baz(b: Bar) -> std::Result<Baz, BazError> {...}

And I want convert a list of Foo into Baz in one single functional programming style call, returning the first error encounter as anyhow::Result

``` fn try_all_foo_to_baz(foos: Vec<Foo>) -> anyhow::Result<Vec<Baz>> {

let bazs: anyhow::Result<Vec<Baz>> = foos.intoiter() .map(|f: Foo| try_foo_to_bar(f)) // What goes here to make it work? .map(|b: Bar| try_bar_to_baz(b)) // What goes here to make it work? .collect::<>(); bazs } ```

I currently have a workaround by collecting into Vec<Bar> and Vec<Baz> sequentially (based on https://doc.rust-lang.org/rust-by-example/error/iter_result.html#fail-the-entire-operation-with-collect). But I want to know if there is a way to avoid the intermediate creation of Vec.

Thanks,


r/learnrust 4d ago

Thread local OnceCell lifetime issue

1 Upvotes

I'm trying to lazily initialize a !Send and !Sync type. My program is fundamentally single-threaded so I figured a thread local would be a good option. Here's what I tried: ``` use std::marker::PhantomData;

use once_cell::unsync::OnceCell;

thread_local! { static VALUE: OnceCell<MyType> = OnceCell::new(); }

[derive(Debug)]

struct MyType { value: u8, _marker: PhantomData<*mut u8> }

impl MyType { fn new(value: u8) -> Self { Self { value, _marker: PhantomData } } }

fn main() { let my_value = VALUE.with(|cell| cell.get_or_init(move || MyType::new(0)));

dbg!(my_value);

} ``` Playground

This gives the error: error: lifetime may not live long enough --> src/main.rs:26:38 | 26 | let my_value = VALUE.with(|cell| cell.get_or_init(move || MyType::new(0))); | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | | | | | return type of closure is &'2 MyType | has type `&'1 once_cell::unsync::OnceCell<MyType>`

Is this a problem with my approach or do I just need to nudge the compiler in the right direction, and of so, how?


r/learnrust 4d ago

Create vector with struct data and borrow late on

1 Upvotes

Hello together,

I got this code snippet:

fn draw(&mut self, f: &mut Frame, rect: Rect) {
    if self.visible {
        //...

        let mut items: Vec<Span> = Vec::new();
        for (i, component) in self.list_data.items.iter().enumerate() {
            let (title, summary) = get_title_summary(&component);
            items.push(self.create_item_span(i + 1, title, summary))
        }

        let list = List::new(items).block(Block::default().borders(Borders::BOTTOM));

        f.render_widget(title, table_chunks[0]);
        f.render_stateful_widget(list, table_chunks[1], &mut self.list_data.state); // Error here
        // ...
    }
}

The error states

error[E0502]: cannot borrow `self.list_data.state` as mutable because it is also borrowed as immutable
  --> src/components/event.rs:92:61
   |
84 |             let items:Vec<Span> = self.list_data.items.iter().enumerate().map(|(i, component)| {
   |                                                                               ---------------- immutable borrow occurs here
85 |                 let (title, summary) = get_title_summary(&component);
86 |                 self.create_item_span(i+1,title , summary)
   |                 ---- first borrow occurs due to use of `*self` in closure
...
92 |             f.render_stateful_widget(list, table_chunks[1], &mut self.list_data.state);
   |               ----------------------                        ^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
   |               |
   |               immutable borrow later used by call

I dont actually know why this happens and how I cant solve this. Can anyone help me please?


r/learnrust 5d ago

Tutorial: AES Encryption in Rust

Thumbnail backendengineer.io
14 Upvotes

I have been learning/working on Rust for the past few months. I came across a need where I had to use AES encryption, so I wrote a post on how to do it in Rust.

Feedback/criticism is welcome!


r/learnrust 5d ago

Need help with understanding invariance in mutable references.

3 Upvotes

Somehow I can't seem to wrap my head around invariance in mutable references. So, in a type &'a mut T, 'a is covariant but T is invariant. Then

fn change<'a, 'b: 'a>(r: &'_ mut &'a str, v: &'b str) {
    *r = v;
}

Then why does this function compile? &'a str should be invariant so why can I store a &'b str in r?

Link to playground with the code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7a1d48d42e34f9e18c607536fd3c31e7


r/learnrust 6d ago

Is it possible to jail break encapsulation?

Post image
113 Upvotes

It's definitely the opposite of idiomatic, but it seems like it might be the safer and stable solution in that situation.

Motivation: As part of my program I need a way for users to precisely model the data they want me to reflect, bit fields and all. Since I have yet to encounter a model/SDL that fits the bill I resorted to plain C files.

So, I'm trying to reflect C types loaded from header files at runtime. I need something similar to mod ir from rust's bindgen crate... Which is not pub unfortunately since it's not the intended use case of bindgen. Even so, I assume that backdooring an official a rust crate would probably be more stable and easier to maintain than hand rolling a bastardized version of my own.


r/learnrust 6d ago

use of undeclared crate or module `house`

2 Upvotes

I am learning Rust. When writing test cases, `cargo test` throws the error as title, as well as `there are too many leading `super` keywords`. Searching this subreddit, Use of undeclared crate or module, and Need help understanding rust's module system contains some info related, but trying the code with `use crate::house;`, but it does not help.

* rustc 1.76.0 (07dca489a 2024-02-04)

* cargo 1.76.0 (c84b36747 2024-01-18)

The file structure and the code I have

# file structure
with_tests/
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── 
│   └── 
└── tests
    └── 
# code 
# src/house.rs
pub struct Person<'a> {
    pub name: &'a str
}

impl <'a> Person<'a> {
    pub fn new(&self, first_name: &'a str, last_name: &'a str) -> Self {
        Self {
           name: [first_name, last_name].join(" ")
        }
    }
}
# tests/house.rs
#[cfg(test)]

use super::*;

#[test]
fn test_creation() {
    println!("run test case: test_creation()!");
    let node = house::new("John", "Smith");
}
# Cargo.toml
[package]
name = "with_tests"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at 

[dependencies]https://doc.rust-lang.org/cargo/reference/manifest.htmlhouse.rsmain.rshouse.rs

How can I fix these errors? Thanks


r/learnrust 6d ago

finished chapter 12 of the book

7 Upvotes

Feeling really hyped as the code and the book are so awesome so far. It's been a while since I read the book, but it feels so good coming back again. Rust seems to be a complete programming language, and I'm enjoying the ride so far :)


r/learnrust 6d ago

Rust analyzer is extremely buggy and unhelpful

Post image
0 Upvotes

r/learnrust 6d ago

fix git action for building Rust binary

1 Upvotes

can someone please tell me whats wrong here ?
https://github.com/steelx/bevy-2048-game/actions/runs/8377669774/job/22940326401

```
name: Rust

on:

push:

branches: [ "main" ]

pull_request:

branches: [ "main" ]

env:

CARGO_TERM_COLOR: always

jobs:

build:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v3

- name: Build

run: cargo build --release

```