How to split the code into files in Rust? [duplicate] - rust

In src/lib.rs I have the following
extern crate opal_core;
mod functions;
mod context;
mod shader;
Then in src/context.rs I have something like this, which tries to import symbols from src/shader.rs:
use opal_core::shader::Stage;
use opal_core::shader::Shader as ShaderTrait;
use opal_core::GraphicsContext as GraphicsContextTrait;
use functions::*; // this import works fine
use shader::*; // this one doesn't
pub struct GraphicsContext {
functions: Gl
}
fn shader_stage_to_int(stage: &Stage) -> u32 {
match stage {
&Stage::Vertex => VERTEX_SHADER,
&Stage::Geometry => GEOMETRY_SHADER,
&Stage::Fragment => FRAGMENT_SHADER,
}
}
impl GraphicsContextTrait for GraphicsContext {
/// Creates a shader object
fn create_shader(&self, stage: Stage, source: &str) -> Box<ShaderTrait> {
let id;
unsafe {
id = self.functions.CreateShader(shader_stage_to_int(&stage));
}
let shader = Shader {
id: id,
stage: stage,
context: self
};
Box::new(shader)
}
}
The problem is that the statement use shader::*; gives the error unresolved import.
I was reading the docs and they said that use statements always go from the root of the current crate (opal_driver_gl) so I thought shader::* should be importing opal_driver_gl::shader::* but it doesn't appear to do so. Do I need to use the self or super keywords here?
Thanks if you can help.

Note that the behavior of use has changed from Rust 2015 to Rust 2018. See What are the valid path roots in the use keyword? for details.
Rust 2018
To import a module on the same level, do the following:
random_file_0.rs
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use crate::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs
mod random_file_0;
mod random_file_1;
See Rust By Example for more information and examples. If that doesn't work, here is the code it shows:
fn function() {
println!("called `function()`");
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
mod my {
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope!
print!("called `my::indirect_call()`, that\n> ");
// The `self` keyword refers to the current module scope - in this case `my`.
// Calling `self::function()` and calling `function()` directly both give
// the same result, because they refer to the same function.
self::function();
function();
// We can also use `self` to access another module inside `my`:
self::cool::function();
// The `super` keyword refers to the parent scope (outside the `my` module).
super::function();
// This will bind to the `cool::function` in the *crate* scope.
// In this case the crate scope is the outermost scope.
{
use cool::function as root_function;
root_function();
}
}
}
fn main() {
my::indirect_call();
}
Rust 2015
To import a module on the same level, do the following:
random_file_0.rs:
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs:
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use ::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs:
mod random_file_0;
mod random_file_1;
Here is another example from a previous version of Rust By Example:
fn function() {
println!("called `function()`");
}
mod my {
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope
print!("called `my::indirect_call()`, that\n> ");
// `my::function` can be called directly
function();
{
// This will bind to the `cool::function` in the *crate* scope
// In this case the crate scope is the outermost scope
use cool::function as root_cool_function;
print!("> ");
root_cool_function();
}
{
// `self` refers to the current module scope, in this case: `my`
use self::cool::function as my_cool_function;
print!("> ");
my_cool_function();
}
{
// `super` refers to the parent scope, i.e. outside of the `my`
// module
use super::function as root_function;
print!("> ");
root_function();
}
}
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
fn main() {
my::indirect_call();
}

Related

Rust: How to import a module in a non main.rs file [duplicate]

In src/lib.rs I have the following
extern crate opal_core;
mod functions;
mod context;
mod shader;
Then in src/context.rs I have something like this, which tries to import symbols from src/shader.rs:
use opal_core::shader::Stage;
use opal_core::shader::Shader as ShaderTrait;
use opal_core::GraphicsContext as GraphicsContextTrait;
use functions::*; // this import works fine
use shader::*; // this one doesn't
pub struct GraphicsContext {
functions: Gl
}
fn shader_stage_to_int(stage: &Stage) -> u32 {
match stage {
&Stage::Vertex => VERTEX_SHADER,
&Stage::Geometry => GEOMETRY_SHADER,
&Stage::Fragment => FRAGMENT_SHADER,
}
}
impl GraphicsContextTrait for GraphicsContext {
/// Creates a shader object
fn create_shader(&self, stage: Stage, source: &str) -> Box<ShaderTrait> {
let id;
unsafe {
id = self.functions.CreateShader(shader_stage_to_int(&stage));
}
let shader = Shader {
id: id,
stage: stage,
context: self
};
Box::new(shader)
}
}
The problem is that the statement use shader::*; gives the error unresolved import.
I was reading the docs and they said that use statements always go from the root of the current crate (opal_driver_gl) so I thought shader::* should be importing opal_driver_gl::shader::* but it doesn't appear to do so. Do I need to use the self or super keywords here?
Thanks if you can help.
Note that the behavior of use has changed from Rust 2015 to Rust 2018. See What are the valid path roots in the use keyword? for details.
Rust 2018
To import a module on the same level, do the following:
random_file_0.rs
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use crate::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs
mod random_file_0;
mod random_file_1;
See Rust By Example for more information and examples. If that doesn't work, here is the code it shows:
fn function() {
println!("called `function()`");
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
mod my {
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope!
print!("called `my::indirect_call()`, that\n> ");
// The `self` keyword refers to the current module scope - in this case `my`.
// Calling `self::function()` and calling `function()` directly both give
// the same result, because they refer to the same function.
self::function();
function();
// We can also use `self` to access another module inside `my`:
self::cool::function();
// The `super` keyword refers to the parent scope (outside the `my` module).
super::function();
// This will bind to the `cool::function` in the *crate* scope.
// In this case the crate scope is the outermost scope.
{
use cool::function as root_function;
root_function();
}
}
}
fn main() {
my::indirect_call();
}
Rust 2015
To import a module on the same level, do the following:
random_file_0.rs:
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs:
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use ::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs:
mod random_file_0;
mod random_file_1;
Here is another example from a previous version of Rust By Example:
fn function() {
println!("called `function()`");
}
mod my {
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope
print!("called `my::indirect_call()`, that\n> ");
// `my::function` can be called directly
function();
{
// This will bind to the `cool::function` in the *crate* scope
// In this case the crate scope is the outermost scope
use cool::function as root_cool_function;
print!("> ");
root_cool_function();
}
{
// `self` refers to the current module scope, in this case: `my`
use self::cool::function as my_cool_function;
print!("> ");
my_cool_function();
}
{
// `super` refers to the parent scope, i.e. outside of the `my`
// module
use super::function as root_function;
print!("> ");
root_function();
}
}
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
fn main() {
my::indirect_call();
}

How to import an implementation of a trait from another module

I have 3 modules
in lib.rs
Module where I'm trying to import impl Test for Block from tra.rs
mod tra;
mod stru;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test() {
use tra::Test; // This doesn't works
let b = stru::Block::new(String::from("Text"));
println!("{}", b.p())
}
}
in stru.rs
Module where struct Block is wrote.
pub struct Block {
text: String
}
impl Block {
pub fn text(&self) -> &String {
&self.text
}
pub fn new(text: String) -> Block {
Block { text }
}
}
in tra.rs
Module where I'm implementing trait Test for Block
#[path = "stru.rs"]
mod stru;
use stru::Block;
pub trait Test {
fn p(&self) -> &String;
}
impl Test for Block {
fn p(&self) -> &String {
self.text()
}
}
I want to import an implementation from tra.rs into lib.rs. How would I do this?
First, you don't import the implementation. You import the trait and that's enough.
Your error is probably because you repeated the mod stru; in tra.rs. Don't. Ever. Define modules in lib.rs only (or submodules, but only if they're sub-sub-modules). Instead, just use it from the crate root:
use crate::stru::Block;
pub trait Test {
fn p(&self) -> &String;
}
impl Test for Block {
fn p(&self) -> &String {
self.text()
}
}

Call Struct Data type in other files [duplicate]

In src/lib.rs I have the following
extern crate opal_core;
mod functions;
mod context;
mod shader;
Then in src/context.rs I have something like this, which tries to import symbols from src/shader.rs:
use opal_core::shader::Stage;
use opal_core::shader::Shader as ShaderTrait;
use opal_core::GraphicsContext as GraphicsContextTrait;
use functions::*; // this import works fine
use shader::*; // this one doesn't
pub struct GraphicsContext {
functions: Gl
}
fn shader_stage_to_int(stage: &Stage) -> u32 {
match stage {
&Stage::Vertex => VERTEX_SHADER,
&Stage::Geometry => GEOMETRY_SHADER,
&Stage::Fragment => FRAGMENT_SHADER,
}
}
impl GraphicsContextTrait for GraphicsContext {
/// Creates a shader object
fn create_shader(&self, stage: Stage, source: &str) -> Box<ShaderTrait> {
let id;
unsafe {
id = self.functions.CreateShader(shader_stage_to_int(&stage));
}
let shader = Shader {
id: id,
stage: stage,
context: self
};
Box::new(shader)
}
}
The problem is that the statement use shader::*; gives the error unresolved import.
I was reading the docs and they said that use statements always go from the root of the current crate (opal_driver_gl) so I thought shader::* should be importing opal_driver_gl::shader::* but it doesn't appear to do so. Do I need to use the self or super keywords here?
Thanks if you can help.
Note that the behavior of use has changed from Rust 2015 to Rust 2018. See What are the valid path roots in the use keyword? for details.
Rust 2018
To import a module on the same level, do the following:
random_file_0.rs
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use crate::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs
mod random_file_0;
mod random_file_1;
See Rust By Example for more information and examples. If that doesn't work, here is the code it shows:
fn function() {
println!("called `function()`");
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
mod my {
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope!
print!("called `my::indirect_call()`, that\n> ");
// The `self` keyword refers to the current module scope - in this case `my`.
// Calling `self::function()` and calling `function()` directly both give
// the same result, because they refer to the same function.
self::function();
function();
// We can also use `self` to access another module inside `my`:
self::cool::function();
// The `super` keyword refers to the parent scope (outside the `my` module).
super::function();
// This will bind to the `cool::function` in the *crate* scope.
// In this case the crate scope is the outermost scope.
{
use cool::function as root_function;
root_function();
}
}
}
fn main() {
my::indirect_call();
}
Rust 2015
To import a module on the same level, do the following:
random_file_0.rs:
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs:
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use ::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs:
mod random_file_0;
mod random_file_1;
Here is another example from a previous version of Rust By Example:
fn function() {
println!("called `function()`");
}
mod my {
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope
print!("called `my::indirect_call()`, that\n> ");
// `my::function` can be called directly
function();
{
// This will bind to the `cool::function` in the *crate* scope
// In this case the crate scope is the outermost scope
use cool::function as root_cool_function;
print!("> ");
root_cool_function();
}
{
// `self` refers to the current module scope, in this case: `my`
use self::cool::function as my_cool_function;
print!("> ");
my_cool_function();
}
{
// `super` refers to the parent scope, i.e. outside of the `my`
// module
use super::function as root_function;
print!("> ");
root_function();
}
}
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
fn main() {
my::indirect_call();
}

How to include a file/module at the same level? [duplicate]

In src/lib.rs I have the following
extern crate opal_core;
mod functions;
mod context;
mod shader;
Then in src/context.rs I have something like this, which tries to import symbols from src/shader.rs:
use opal_core::shader::Stage;
use opal_core::shader::Shader as ShaderTrait;
use opal_core::GraphicsContext as GraphicsContextTrait;
use functions::*; // this import works fine
use shader::*; // this one doesn't
pub struct GraphicsContext {
functions: Gl
}
fn shader_stage_to_int(stage: &Stage) -> u32 {
match stage {
&Stage::Vertex => VERTEX_SHADER,
&Stage::Geometry => GEOMETRY_SHADER,
&Stage::Fragment => FRAGMENT_SHADER,
}
}
impl GraphicsContextTrait for GraphicsContext {
/// Creates a shader object
fn create_shader(&self, stage: Stage, source: &str) -> Box<ShaderTrait> {
let id;
unsafe {
id = self.functions.CreateShader(shader_stage_to_int(&stage));
}
let shader = Shader {
id: id,
stage: stage,
context: self
};
Box::new(shader)
}
}
The problem is that the statement use shader::*; gives the error unresolved import.
I was reading the docs and they said that use statements always go from the root of the current crate (opal_driver_gl) so I thought shader::* should be importing opal_driver_gl::shader::* but it doesn't appear to do so. Do I need to use the self or super keywords here?
Thanks if you can help.
Note that the behavior of use has changed from Rust 2015 to Rust 2018. See What are the valid path roots in the use keyword? for details.
Rust 2018
To import a module on the same level, do the following:
random_file_0.rs
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use crate::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs
mod random_file_0;
mod random_file_1;
See Rust By Example for more information and examples. If that doesn't work, here is the code it shows:
fn function() {
println!("called `function()`");
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
mod my {
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope!
print!("called `my::indirect_call()`, that\n> ");
// The `self` keyword refers to the current module scope - in this case `my`.
// Calling `self::function()` and calling `function()` directly both give
// the same result, because they refer to the same function.
self::function();
function();
// We can also use `self` to access another module inside `my`:
self::cool::function();
// The `super` keyword refers to the parent scope (outside the `my` module).
super::function();
// This will bind to the `cool::function` in the *crate* scope.
// In this case the crate scope is the outermost scope.
{
use cool::function as root_function;
root_function();
}
}
}
fn main() {
my::indirect_call();
}
Rust 2015
To import a module on the same level, do the following:
random_file_0.rs:
// Note how this is a public function. It has to be in order to be
// usable from other files (in this case `random_file_1.rs`)
pub fn do_something() -> bool {
true
}
random_file_1.rs:
use super::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
or an alternative random_file_1.rs:
use ::random_file_0;
#[test]
fn do_something_else() {
assert!(random_file_0::do_something());
}
lib.rs:
mod random_file_0;
mod random_file_1;
Here is another example from a previous version of Rust By Example:
fn function() {
println!("called `function()`");
}
mod my {
pub fn indirect_call() {
// Let's access all the functions named `function` from this scope
print!("called `my::indirect_call()`, that\n> ");
// `my::function` can be called directly
function();
{
// This will bind to the `cool::function` in the *crate* scope
// In this case the crate scope is the outermost scope
use cool::function as root_cool_function;
print!("> ");
root_cool_function();
}
{
// `self` refers to the current module scope, in this case: `my`
use self::cool::function as my_cool_function;
print!("> ");
my_cool_function();
}
{
// `super` refers to the parent scope, i.e. outside of the `my`
// module
use super::function as root_function;
print!("> ");
root_function();
}
}
fn function() {
println!("called `my::function()`");
}
mod cool {
pub fn function() {
println!("called `my::cool::function()`");
}
}
}
mod cool {
pub fn function() {
println!("called `cool::function()`");
}
}
fn main() {
my::indirect_call();
}

Access to self from the parameters of a macro that creates a struct

I'm trying to write a macro that generates a struct. The implementation for the struct will be generated by the macro, but some blocks of code will be provided as macro arguments. Here is a minimal example of such a macro:
macro_rules! make_struct {
($name:ident $block:block) => {
struct $name {
foo: i32,
}
impl $name {
fn new() -> Self {
$name { foo: 42 }
}
fn act (&self) {
$block
}
}
};
}
And here is an example of how the macro can be used:
fn main() {
// Works
make_struct!(Test { println! ("Bar: {:?}", 24); });
let test = Test::new();
test.act();
}
I would like to give access to self inside the supplied code. Something like:
fn main() {
// Does not work
make_struct!(Test { println! ("Foo: {:?}", self.foo); });
let test = Test::new();
test.act();
}
I understand that this does not work because of macro hygiene rules. Specifically, the self.foo expression is evaluated in the syntax context of the main function, where self does not exist. The question is: is there a way to modify the macro so that self may be accessed from the user-supplied code?
Code on playground
You can pass a closure instead of a block.
make_struct!(Test |this| println!("Foo: {:?}", this.foo));
Then the macro can use the closure and call it with self:
macro_rules! make_struct {
($name:ident $closure:expr) => {
struct $name {
foo: i32,
}
impl $name {
fn new() -> Self {
$name { foo: 42 }
}
fn act (&self) {
let x: &Fn(&Self) = &$closure;
x(self)
}
}
};
}
The dance with the let binding is necessary, because the type of this in the closure can't be inferred (yet?). And it also makes your macro's error reporting a little more readable when something other than a closure is passed.
Found a way to do it by adding a parameter to the macro that stores the name by which self will be accessed in the blocks:
macro_rules! make_struct {
($myname:ident : $type_name:ident $block:block) => {
struct $type_name {
foo: i32,
}
impl $type_name {
fn new() -> Self {
$type_name { foo: 42 }
}
fn act (&self) {
let $myname = self;
$block
}
}
};
}
fn main() {
make_struct!(myself: Test { println! ("Foo: {:?}", myself.foo); });
let test = Test::new();
test.act();
}

Resources