fn main() {
    // main_with_tuple();
    main_with_struct();
    // two values are unrelated in the code, only by name
    // let length1 = 8;
    // let width1 = 4;

    // println!("The area of a rectangle is {} square units.",
    // area(length1, width1)
    // )
}

fn area (length: i32, width: i32) -> i32 {
    length * width
}

fn main_with_tuple () {
    // vaules are related now but no distinction between length and width
    // less clear, would have to remember that the first value is the length and second is width if used anywhere else such as drawing to the screen
    let rectangle1 = (8, 4);
    println!("The area of a rectangle is {} square units.",
    area_with_tuple(rectangle1)
    );
}

// only needs one argument
fn area_with_tuple (dimensions: (i32, i32)) -> i32 {
    // much less clear what is going on here, names only help a bit
    dimensions.0 * dimensions.1
}

struct Rectangle {
    // negative length/width shapes dont exist
    length: u32,
    width: u32,
}
fn main_with_struct () {
    // clearly defined what is going on without the need of comments
    let rect1 = Rectangle {
        length: 8,
        width: 4,
    };
    println!("The area of a rectangle is {} square units.",
    area_with_struct(&rect1)
    );
}

// prefer to borrow a struct rather than own
fn area_with_struct (rect: &Rectangle) -> u32 {
    // way mroe clear the relationship between the two values
    rect.length * rect.width
}