Maxxxxz
Maxxxxz

Reputation: 3

Rust different types when referring to same file

I've come across a problem while attempting to use a custom enum across multiple files in Rust. I would expect to be able to write one file that contains this enum and reference it from multiple files (file_a.rs runs a function that returns a Shape enum, main.rs matches the type, but it expects types::Shape and finds a file_a::types::Shape). The outcome I expect is that both are of type types::Shape, but this does not seem to be the case.

In the past, to fix this problem, I have simply put all of the code that creates these conflicts into the same file. This does not seem like a proper solution, and especially not a professional one.

I have not been able to find any articles or questions that deal with using enums across different files in the way that I am (please direct me to them if you can).

How can I use an enum across multiple files while keeping it's type the same across all of them?

Here is a small example that demonstrates the problem. The errors occur in main.rs in the match statement.

Directory structure:

src
|    main.rs
|____core
|   |    types.rs
|   |    file_a.rs

/src/main.rs:

#[path = "./core/types.rs"]
mod types;
use types::*;

#[path = "./core/file_a.rs"]
mod file_a;
use file_a::*;

fn main()
{
    match return_a_shape()
    {
        Shape::CIRCLE => println!("circle"),        // expected enum `file_a::types::Shape`, found enum `types::Shape`
        Shape::SQUARE => println!("square"),        // expected enum `file_a::types::Shape`, found enum `types::Shape`
        Shape::TRIANGLE => println!("triangle"),    // expected enum `file_a::types::Shape`, found enum `types::Shape`
        _ => println!("unknown shape"),
    }
}

/src/core/file_a.rs:

mod types;
use types::*;

pub fn return_a_shape() -> Shape
{
    return Shape::CIRCLE;
}

/src/types.rs:

pub enum Shape
{
    SQUARE,
    CIRCLE,
    TRIANGLE,
}

Upvotes: 0

Views: 2086

Answers (1)

Nina Lisitsinskaya
Nina Lisitsinskaya

Reputation: 1818

I'm just studying rust, but as far as I understand, the problem here is not in the enum, but in the mod. This keyword turns one module into a submodule of another module. So, when you make types into a submodule of both file_a and main, it is imported twice as two different modules.

You can delete mod types; line from the file_a.rs and import it from parent module as use super::types::*;.

use super::types::*;

pub fn return_a_shape() -> Shape
{
    return Shape::CIRCLE;
}

Or you can import types module into the file_a but not in the main module, and reexport it:

file_a.rs

pub mod types; // Import types as a submodule and reexport it
use types::*;

pub fn return_a_shape() -> Shape
{
    return Shape::CIRCLE;
}

main.rs

#[path = "./core/file_a.rs"]
mod file_a;
use file_a::*;
use file_a::types::*; // Use types submodule from the file_a module

fn main()
{
    match return_a_shape()
    {
        Shape::CIRCLE => println!("circle"),
        Shape::SQUARE => println!("square"),
        Shape::TRIANGLE => println!("triangle"),
        _ => println!("unknown shape"),
    }
}

Upvotes: 2

Related Questions