gamedig / rust-gamedig

Game Server Query Library.
https://crates.io/crates/gamedig
MIT License
35 stars 10 forks source link

feat: Find alternatives to PHF for conditional compiling. #200

Open CosminPerRam opened 2 months ago

CosminPerRam commented 2 months ago

Describe the problem When Ark: Survival Ascended was added in #197 we couldn't add it to the games definitions because the game (and protocol) is available only through the tls feature to avoid adding another hard dependency.

And we can't use conditional stuff with PHF in the way we use it now.

Possible solutions

  1. Swap phf with phf_codegen and create a build.rs script. Advantages: the fastest solution as this will generate and make the hashmap available at compile time. Disadvantages: negligible bigger compile time I guess? and I for one am not really a fan of build scripts.
  2. Use lazy_static! (or an equivalent). Advantages: Easiest to use and fastest to transition to. Disadvantages: The first call will take a while to compute (but considering that everything that we use is const, the only overhead should be just the hashmap construction and inserts (dont quote me on this)) and therefore isn't really great for CLI performance. Here is a quick snippet of a poc of the usage:

use std::collections::HashMap; use lazy_static::lazy_static;

lazy_static! { static ref HASHMAP: HashMap<u32, &'static str> = { let mut m = HashMap::new(); m.insert(0, "foo");

[cfg(feature = "some_feature")]

    m.insert(1, "baz");
    m
};

}

fn main() { println!("{:#?}", HASHMAP.get(&1)); }


3. Use phf for a 'default' hashmap and extend it with `lazy_static` only if we enable certain features.
I haven't looked that much into this but it's something that came up when I wrote this.
Douile commented 2 months ago

I don't think option 3 is possible because phf generates a hash function that is perfect for the things that exist at compile time. We would need 2 hash maps, then I guess to lookup check the phf one then the runtime one.

I don't think lazy static is a bad option: using normal hashmaps also allows the option for expanding game list at runtime.

There's also option 4 of adding support for cfg to the phf proc macro

Or option 5 of not feature gating tls, always have everything enabled. I'm not a big fan of that because it means consumers have less control of how they consume the library. However I don't imagine many situations where people wouldn't want tls support unless they just want a specific game.