Converting simple idiomatic C to idiomatic Rust

Consider three C header files a.h, b,h and c.h.

Also, you have three source files.
p.c:

#include "a.h"
...

q.c:

#include "b.h"
#include "c.h"
...

r.c:

#include "a.h"
#include "c.h"
...

The source files compile to p.o, q.o and r.o respectively.

Then the object files are linked to get lib.a, a static library.

What is the intended way to do the same thing on Rust?

I am assuming that you do it by mapping source file x.c to crate x. If that is the case, what is the equivalent of the header files in Rust?

Rust has no concept of header files.
In C you usually have pairs of .c and .h files. Each of these pairs corresponds to a single .rs file in Rust.
That means that you will have 6 source files:
a.rs, b.rs, c.rs, p.rs, q.rs, r.rs. Each of those files represents a so called "module" (not a crate).
Additionally you need a library source file lib.rs which is the root module and ties the submodules together:

lib.rs:

mod a;
mod b;
mod c;
mod p;
mod q;
mod r;

Now if you want to use a module from another module, this is done as follows:

p.rs:

use crate::a::*;

q.rs:

use crate::b::*;
use crate::c::*;

r.rs:

use crate::a::*;
use crate::c::*;

All this together is called a crate, which is just the rust term for a library (or executable).

lib.a is equivalent of a Rust crate (in fact, you can compile a crate to a C-compatible static library).

Crates can be composed from modules, which are typically one .rs file per module, so they're sort-of a bit like .c files, but modules are namespaced, and one .rs file can actually define multiple modules inline.

There are no headers in Rust. Cargo and rust compiler will automatically handle all the "header-like" metadata for you, so your code can refer to other modules, dependencies, etc. without ever needing manually managing headers.

4 Likes

Is it possible to do this without having to explicitly put pub before every member in the module?

To use a member outside of the module, you must use pub.

No, and additionally to use the modules from another crate, you also have to add another pub for each public module, like:

pub mod a;
pub mod b;
...

Thanks, the crate keyword helped. Prior to this, I was using the path attribute which complicated the issue very quickly. Marked as solved.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.