We have lots of functions handling various cases. These are divided into multiple modules based on the types of the cases.
The nice thing seem to be is creating a dispatch table mapping strings to functions.
Each module is responsible for returning a DispatchTable. There is a central function that combines them.
We could generate this up-front and then pass the DispatchTable to each function but it seemed better to get the DispatchTable internally.
If we do that we'll recreate the DispatchTable in every call. Using the cached crate allows us to eliminate all the calls but the first one.
examples/cache-dispatch-table/src/main.rs
use cached::macros::cached;
mod locations;
mod other;
mod types;
use crate::types::DispatchTable;
fn main() {
for name in &["city", "state", "country", "language"] {
process(name);
}
}
fn process(name: &str) {
let dispatch = get_dispatch();
println!("Processing: {name}");
if let Some(process_fn) = dispatch.get(name) {
let result = process_fn();
println!("{}", result);
}
println!();
}
#[cached]
fn get_dispatch() -> DispatchTable {
println!("get_dispatch called");
let mut config = DispatchTable::new();
let cfg = crate::locations::get_dispatch();
for (key, value) in cfg {
config.insert(key, value);
}
let cfg = crate::other::get_dispatch();
for (key, value) in cfg {
config.insert(key, value);
}
config
}
examples/cache-dispatch-table/src/locations.rs
use crate::types::DispatchTable;
fn process_city() -> &'static str {
"Processing city of Seoul"
}
fn process_country() -> &'static str {
"Processing country of Korea"
}
pub(crate) fn get_dispatch() -> DispatchTable {
println!("get_dispatch for locations called");
let mut config = DispatchTable::new();
config.insert("city", process_city);
config.insert("country", process_country);
config
}
examples/cache-dispatch-table/src/other.rs
use crate::types::DispatchTable;
fn process_language() -> &'static str {
"Processing the Korean language"
}
pub(crate) fn get_dispatch() -> DispatchTable {
println!("get_dispatch for locations called");
let mut config = DispatchTable::new();
config.insert("language", process_language);
config
}
examples/cache-dispatch-table/src/types.rs
use std::collections::HashMap;
pub(crate) type Handler = fn() -> &'static str;
pub(crate) type DispatchTable = HashMap<&'static str, Handler>;
examples/cache-dispatch-table/out.txt
get_dispatch called
get_dispatch for locations called
get_dispatch for locations called
Processing: city
Processing city of Seoul
Processing: state
Processing: country
Processing country of Korea
Processing: language
Processing the Korean language
examples/cache-dispatch-table/Cargo.toml
[package]
name = "cache-dispatch-table"
version = "0.1.0"
edition = "2024"
[dependencies]
cached = "2.0.2"