Rust - Renaming without restructuring

Previously published

This article was previously published on len-learns-rust.com. A full index of these articles can be found here.

We now have a ThreadSafeIdManager that can provide SmartId’s. It would probably be better to simply have an IdManager that provides Id’s, especially since, in Rust, we can’t even reliably use the original IdManager implementation.

I’m adverse to renaming the code at this point as that breaks the ease of comparison with earlier versions. I could, of course, shuffle all the code around, rename files and change modules but, to be honest, the whole module structure is also a bit unwieldy at present. We have a crate called ‘idmanager’ which contains several types we wont use publicly and several that we will but each of the ones we will use is in a different module. I like the fact that the code for each object is in separate files, but perhaps that’s the ‘C++’ programmer poking through…

Luckily, there’s a way to fix all of these issues without too much code change. I learnt all about this from Gian Lorenzetto in his article about Rust modules and project structure. What we need to do is make all the modules private and then expose the types we want, with the names we want using ‘pub use’. The only change required here is to adjust our lib.rs file:

mod interval;
mod intervals;
mod id_manager;
mod smart_id;
mod thread_safe_id_manager;

pub use thread_safe_id_manager::ThreadSafeIdManager as IdManager;
pub use smart_id::SmartId as Id;

We now have two public types, IdManager and Id. Given we’ve erased the whole ‘smart id’ name we should probably fix up the allocation function, renaming it from allocate_smart_it() to allocate_id() and since, at present at least, the only safe way to use ids is to use the RAII[^1] wrapper Id we can make the bare allocate() and free() functions private.

This leaves us with a usage example of:

extern crate idmanager;

use idmanager::IdManager;

pub fn main() {
    let manager = IdManager::new();

    assert_eq!(manager.dump(), "[0,255]");

    {
        let id = manager.allocate_id();

        let expected_id : u8 = 0;

        assert_eq!(id.value(), &expected_id);

        assert_eq!(manager.dump(), "[1,255]");
    }

    assert_eq!(manager.dump(), "[0,255]");
}

Which is much cleaner.

Join in

The code can be found here on GitHub each step on the journey will have one or more separate directories of code, so this article’s code is here, this allows for easy comparison of changes at each stage.

Of course, there may be a better way; leave comments if you’d like to help me learn.

s