Reputation: 3
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
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