Search code examples
rustrust-cargo

Making a fahrenheit to celsius converter and getting E0502


The goal is to make a program where from an input such as 56c or 36f it would understand which scale we are using and then convert accordingly. This is the current code:

use std::io;

fn main() {
    println!("Please input temp in format 35f/35c: ");
    let mut input = String::new();

    io::stdin()
        .read_line(&mut input)
        .expect("Failed to read line");

    let len = input.trim().len();
    let unit = &input[len - 1..];
    input.truncate(len - 1);
    if unit == "f" {
        let result = fahrenheit_to_c(input.parse::<i32>().unwrap());
        println!("{result}");
    } else if unit == "c" {
        let result = celsius_to_f(input.parse::<i32>().unwrap());
        println!("{result}");
    } else {
        println!("Please make the correct input!");
    }
}

fn fahrenheit_to_c(tempr: i32) -> i32 {
    (tempr - 32) * 5 / 9 as i32
}

fn celsius_to_f(tempr: i32) -> i32 {
    (tempr * 9 / 5) + 32 as i32
}

Result output worked when I tested it without the if statements, after I added if statements I started getting this

error[E0502]: cannot borrow `input` as mutable because it is also borrowed as immutable
  --> src/main.rs:13:5
   |
12 |     let unit = &input[len - 1..];
   |                 ----- immutable borrow occurs here
13 |     input.truncate(len - 1);
   |     ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
14 |     if unit == "f" {
   |        ---- immutable borrow later used here        

I've tried having scale and temperature as different two different inputs to make the type conversion simplier but that's not what im aiming for here.


Solution

  • You cannot modify input after you take a shared reference to it that you still use. let unit = &input[len - 1..]; takes a shared reference to input.

    Instead you can get two separated slices, value and unit with a simple split_at:

        let (value, unit) = input.split_at(len - 1);
    

    now you can parse that value and use unit to decide how to handle it.

    You'll still want to clean up unit because it still contains the "\n" the user put in.