How to document a binary Rust crate project? - rust

I have a program that I've written in Rust and I would like document it. I've looked on line and found:
https://doc.rust-lang.org/stable/rust-by-example/meta/doc.html
https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text
I've added doc comments to the code:
/// This is a documented function
fn example() {
println!("Hi there");
}
The problem I'm having now is that after I run cargo doc, I get all the other documentation generated for all the crates my program uses, but the HTML documentation does not induce my program. I've been looking around and I haven't see anything that talks about just documenting a single program, usually I see material about documenting crates. If I can use Rust's documentation system for a stand alone program, how would can I do this?

The problem is that your function is private (which makes sense for a binary crate). However, rustdoc currently only documents public items by default (which makes sense for a library crate). You can use the flag --document-private-items to also include private functions and the like:
cargo doc --document-private-items
There is some discussion about this feature and the default we should be using here.
Furthermore, I recently opened a PR to change the default behavior for binary crates, so that private item for binary crates are documented by default. This change is expected to arrive on the stable compiler on January the 31st 2020 (1.41.0).

Related

Runtime plugins in Rust

We have a commercially sold application that is presently written in Java and Python. We are currently looking at moving to Rust for performance and non-crashy reasons.
In our present Java/Python architecture, we have a feature that manages customisations that particular customers want. This involves placing Java jars/classes and python files under a specific folder designated for customisation for specific customers. In the application configuration, the Java classpath and the PYTHON_PATH have this folder precede the folders containing the normal, uncustomised application code. Because of this, any code in this special folder will override the normal, uncustomised behaviour of the application.
We would like to keep this feature in some form when moving to Rust. We certainly want to avoid distributing source code to our customers for the core app (mostly Java now) and have customers compile, which is what we would need to do if we used Rust's module feature.
Is there a way we can we implement this feature when we go to Rust?
Target OS's are a mix of Linux and Windows.
Sounds like you want some kind of plugin architecture, with a dynamic library (also written in Rust) that's loaded at runtime.
Unfortunately, Rust doesn't have a stable ABI yet, meaning that those librarise would have to be compiled with the exact same compiler that built the main application. One workaround is to expose a C ABI from the plugin side, and use C FFI to call it, if you can live with the unsafety and hassle that entails. There's also the abi_stable crate, which might be safer/simpler to use.
Scripting languages might be another avenue to explore. For example, Rhai is a language specifically developed for use in Rust applications, and interoperates as seamlessly as these things get. Of course, performance of the scripted parts will not be as great as native Rust code.
I don't think that it is possible without recompiling it or at least compiling the config.rs file that you intend to create for individual users.
Assuming that the end user does not have Rust installed on their system, a few alternatives might be:
Using .yaml files for loading configs (similar to how GitHub Actions work)
Allowing users to run custom programs (you can use tokio::process to run them in an async manner)
Using rhaiscript (I personally prefer this option)
Taken from the official language docs for the modules feature
you could set up your commercial project in such a way that the source code is threated as an external crate, and then load it into the main project with the path attribute.
A minimal example, already on the docs:
#[path = "thread_files"]
mod thread {
// Load the `local_data` module from `thread_files/tls.rs` relative to
// this source file's directory.
#[path = "tls.rs"]
mod local_data;
}

How to extract nightly features used in a crate?

I want to extract all nightly features used by a crate for some research purposes.
Just to be clear, "nightly features" means codes like #![feature(...)]", but not crate provided optional features.
I tried using regex, and it works, but not accurate enough. cfg defined features may not be detected: #![cfg_attr(target_os = "macos", feature(...))].
So I turn to rustc compiler, I wish to modify some source code and print out what features crate uses. Now I'm still trying to find out how rustc deals with nightly features.
I hope someone can give me some tips and help about the process of rustc dealing with nightly features. I'm almost lost in codes.
Access to enabled features is done via rustc_session::Session::features. You can add code after they are set in rustc_interface, or look at how they're computed.
If you are at a later stage, you probably have access to the Session of the compiled crate. For example, TyCtxt has a sess() method (but also a features() method for direct access using the query system), and InferCtxt has a tcx member to access the TyCtxt.

How are Rust crates (e.g. num_cpus) implemented?

I was wondering how are Rust crates are implemented.
For example, there is a crate named num_cpus. This crate has this basic method num_cpus::get() which tells number of CPUs in your computer.
My questions:
How is the method num_cpus::get() implemented (is it done using another language?)
Can the same result be achieved with plain Rust code without using any crates?
... in Rust. There's no reason to believe it'd be anything else.
You can also check this by just looking at the source code, easily done by:
Search crates.io for "num_cpus"..
Select the num_cpus crate.
Select "Repository" for the source code.
Open the only .rs source file in the repository, src/lib.rs.

Is there a way to detect the compiler version from within a Rust program?

In C++, you could use something like __clang_version__. Is there something similar for Rust? I searched on the internet, but found nothing.
Not directly.
There is the rustc_version crate which tells you the version of rustc accessible on the command-line; this is designed to be used in a build script. There's also rustc_version_runtime which does something similar, but exposes the information as a runtime call (i.e. it detects the compiler version at compile time, but exposes it at runtime).
Standard disclaimer: be very careful writing anything that depends on compiler version. You should ideally only test for minimum versions for which features are supported using semver (which both of the above libraries support directly).

inspect rust traits at runtime

is there a way to inpect the traits an object provides at runtime. Similar to pythons dir()? I wish to inspect the contents of a core::str::StrSplits<'_> and would like to be able to view the traits it implements.
There is no facility for doing this at runtime; at compile time, however, there is, and this is what rustdoc does.
With that you can see things like the core::str::StrSplits documentation which covers the information you requested.

Resources