Can I rename lib.rs to the crate name? - rust

Right now I'm working on a project with multiple separate crates.
I would prefer lib.rs to be renamed to the crate's name itself, as when I open multiple at the same time it takes me an extra second to find the one I'm looking for, not a big deal just curious if it's possible or a good idea.
ne_log/lib.rs into: ne_log/ne_log.rs

Yes, in each Cargo.toml add a lib section with the desired path:
[lib]
path = "src/some_other_file.rs"
Read more here: Cargo Targets
As to whether its a good idea or not; it will make your file structure non-standard, but the option is available since there are plenty of non-standard workflows. Use your own discretion.

Related

How do I find the path to the home directory for Linux?

I need the path contained in $HOME, the path to the home directory. The function home_dir seems to do exactly that but is deprecated. What should I use in its place?
The documentation says this :
Deprecated since 1.29.0:
This function's behavior is unexpected and probably not what you want. Consider using a crate from crates.io instead.
What type of crate should I use instead? Is there really no alternative in standard Rust?
From the home crate.
The definition of home_dir provided by the standard library is incorrect because it relies on the $HOME environment variable which has basically no meaning in Windows. This causes surprising situations where a Rust program will behave differently depending on whether it is run under a Unix emulation environment. Neither Cargo nor rustup use the standard libraries definition - instead they use the definition here.
There is discussion about bringing home_dir back into the standard library, but for now the home crate is probably your best option. It provides canonical definitions of home_dir, cargo_home, and rustup_home:
match home::home_dir() {
Some(path) => println!("{}", path.display()),
None => println!("Impossible to get your home dir!"),
}
From the dirs crate.
Note that the crate provides paths to many standard directories as defined by operating systems rules, not only the home directory:
Experience has shown that 90% of those asks for $HOME are better served by one of the other functions this crate provides.
If your requirements are more complex, e. g. computing cache, config, etc. paths for specific applications or projects, consider using the directories crate instead.

Remove crate feature

I'm loading a crate in my project and this crate has a feature called object-pooling that is not thread safe. Someone suggested I remove this functionality from the crate but I don't know how to do that. Is there a special entry that I can add to my Cargo.toml file and disables features from dependencies?
The syntax in your CARGO.TOML is:
crate_name = {version="version_numer", features=[feature1, feature2]}
If you want or don't want to have a specific feature you can adapt the features list.
Check out the crates documentation or sourcecode if you want to know which features provide which functionality.
You can find the available features of your specific crate here:
https://github.com/brave/adblock-rust/blob/master/Cargo.toml#L86

Setting the include path with bindgen

I'm writing a Rust interface to a small C library, which has headers spread in a few locations. It's not a system library, and is normally used by some executables in the same package; I'm currently including it as a git submodule in my Cargo project.
Building the library seems to be pretty easy; I've opted to use the gcc crate from build.rs:
gcc::Config::new()
.file("external/foo/dir1/file1.c")
.file("external/foo/dir2/file2.c")
.include("external/foo/dir1/")
.include("external/foo/dir2/")
.include("external/foo/config_a/")
.compile("libfoo.a");
Now I was hoping to use the bindgen crate to generate the FFI interface without too much fuss, but it doesn't seem to have a way of setting include paths.
I can create a wrapper.h as suggested by this blog and include several headers, but if dir1/dir1.h includes conf.h directly, which works when building due to .include("external/foo/config_a/") it can't be found.
I can't find anything in bindgen's API to help here (essentially I want to pass the equivalent of gcc/clang's -I option). Am I missing anything?
The best option I can think of so far is to copy the various headers from the library source into some temporary directory in build.rs and run bindgen on that, but that seems somewhat messy if there's a nicer way.
With the API you can use Builder::clang_arg with arbitrary arguments:
let b = bindgen::builder().header("foo.h").clang_arg("-I/path");
From the command line you can do the same by appending arguments after --, like:
bindgen foo.h -- -I/path

Global feature gates in Cargo

I would like to enable a feature gate for my entire Cargo project. For example, I would like #![feature(non_ascii_idents)] added to every source file. Is there a place to list them in Cargo.toml?
No, though you don't add feature gates to every source file; they are crate attributes. That is, you set them on the crate, not on every module.
There are two types of attributes:
file attributes (starting with #). They apply to the whole file only.
crate attributes (starting with #!). They apply to the whole crate at once.
What you want (#![feature(non_ascii_idents)]) is a crate attribute, so you need to place it once at the top of the crate's main file. That main file is usually:
src/main.rs for binaries
src/lib.rs for libraries

Multiple Rust source files for cargo

If I have multiple .rs files in the src directory of a Cargo package, what are the rules for visibility, importing, etc.?
Currently, any extra (i.e. not the file that is explicitly identified as the source for the executable in Cargo.toml) files are ignored.
What do I need to do to fix this?
There is nothing special about Cargo at all in this way. It’s all the perfectly normal Rust module system. If Cargo will be compiling src/lib.rs, that’s more or less equivalent to having executed rustc --crate-type lib src/lib.rs (there are more command line arguments in practice, but that’s the basics of it).
Other files are then used with mod, use and so forth. Files are not automatically imported or anything like that. This part is not documented very clearly yet; a couple of things that show briefly how to achieve things are http://rustbyexample.com/mod/split.html and http://doc.rust-lang.org/reference.html#modules, but any non-trivial code base will use them and so you can pick just about any code base to look at for examples.
It's hard to say what you're getting tripped up on from the info you shared. Here are three seemingly trivial things that I still had to refer to the documentaton to figure out:
First of all,
mod foo;
looks like a declaration, but it without arguments it is actually something like an include. So you use the same keyword both for declaring and including modules, i.e. there is no using:: keyword.
Second, modules themselves can be public or private. If you didn't add a pub keyword both on the function in question AND on the containing module, that may be tripping you up.
pub mod foo {pub fn bar();}
Third, there seems to be an implicit module added at the top of every file. This is confusing; the reference manual talks about a strict separation between file paths and names, and the module paths in your code, but that abstraction seems to be leaky here.
Note, Rust is still pre-1.0 (0.12) at the time of writing, at the module system and file paths are relatively high level, so don't be surprised if what I said may already wrong by the time you read this.
Files are implicitly included from your rust code.
For instance, if a file src/foo.rs pointed by path in a [lib] or [[bin]] section of your Cargo.toml contains:
mod bar;
It tells cargo to build src/bar.rs too, and include it.

Resources