Register own crates

Hi,
I'm creating my first project in Rust. I use workspace for seperate functionality.
My folder structure:

project
 |-api
 | |-src
 | | |-lib.rs
 |-core
 | |-src
 | | |-lib.rs
 | | |-modules.rs
 | | | ...
 |-nms
 - Cargo.toml

nms crate is binary which runs core::init(). I'd like register api crate in core crate and api doesn't depend on core.
core/src/lib.rs

pub fn init(){
// modules to register
// registration has fire `module`::register() function in each module
let modules = vec!["api"];

println!("Launching register..");
// Register modules
modules::register_modules(&modules);

// Start Rocket
router::init();
}

core/src/modules.rs

pub fn register_modules<'a>(modules: &'a Vec<&str>) -> &'a Vec<&'a str> {

    print!("Registering modules ...");
    for module in modules {
        print!(" {}", module);

        // here I'd like to fire module::register() function
        // in api case it is api::register()

    }

    println!("\n");

    &modules
}

api/src/lib.rs

pub fn register() {
    println!("I'm api module. Thanks for registering me");
}

I don't have any idea how to run api::register() function as "dynamic".
Any hints?

Crate names and function names don't exist at runtime, they could have been renamed to something unrecognizable or eliminated entirely by the compiler. You could use dynamic linking: have api be a cdylib, and then load it at runtime, but this is probably not a good idea. What are you trying to achieve here? Why can you not just call api::register() directly?

This may get you closer, but I'm unclear on your exact goal as well.

If you want to associate strings with functions, you're going to have to build that into your program yourself with a HashMap or more involved machinery.

Thank you for your reply.
@Kestrer Calling api::register() directly it would be the easiest way. I'd like to create something dynamic. This project will be simple web service with seperated crates api, http and other. api and http will be adding endpoints to Rocket and It would be excelent if endpoints will be added dynamicly not manually. But I think I'm do it wrong, because in my case core depends of api and if api must call methods from core so, api needs dependency of core, so I'm creatig circular dependecy :frowning:
I think I should create methods in core, and api must depend on core and call methods from it. Every crate a should be initialized/registered in main() function. Is it right?

@quinedot Your example exlplain a lot. I didn't thought abot closures but this is solution.