Expand description
§Concrete Type
A procedural macro library for mapping enum variants to concrete types.
This crate provides two main derive macros:
Concrete- For enums where each variant maps to a specific concrete typeConcreteConfig- For enums where each variant has associated configuration data and maps to a specific concrete type
These macros enable type-level programming based on runtime enum values by generating helper methods and macros that provide access to the concrete types associated with enum variants.
§Examples
§Basic Usage with Concrete
ⓘ
use concrete_type::Concrete;
#[derive(Concrete, Clone, Copy)]
enum Exchange {
#[concrete = "exchanges::Binance"]
Binance,
#[concrete = "exchanges::Coinbase"]
Coinbase,
}
mod exchanges {
pub struct Binance;
pub struct Coinbase;
impl Binance {
pub fn new() -> Self { Binance }
pub fn name(&self) -> &'static str { "binance" }
}
impl Coinbase {
pub fn new() -> Self { Coinbase }
pub fn name(&self) -> &'static str { "coinbase" }
}
}
// Use the auto-generated exchange! macro for type-level dispatch
let exchange = Exchange::Binance;
let name = exchange!(exchange; ExchangeImpl => {
// ExchangeImpl is aliased to the concrete type (exchanges::Binance)
let instance = ExchangeImpl::new();
instance.name()
});
assert_eq!(name, "binance");§Using ConcreteConfig with Configuration Data
ⓘ
use concrete_type::ConcreteConfig;
// Define concrete types and configuration types
mod exchanges {
pub trait ExchangeApi {
type Config;
fn new(config: Self::Config) -> Self;
fn name(&self) -> &'static str;
}
pub struct Binance;
pub struct BinanceConfig {
pub api_key: String,
}
impl ExchangeApi for Binance {
type Config = BinanceConfig;
fn new(_: Self::Config) -> Self { Self }
fn name(&self) -> &'static str { "binance" }
}
}
// Define the enum with concrete type mappings and config data
#[derive(ConcreteConfig)]
enum ExchangeConfig {
#[concrete = "exchanges::Binance"]
Binance(exchanges::BinanceConfig),
}
// Using the auto-generated macro with access to both type and config
let config = ExchangeConfig::Binance(
exchanges::BinanceConfig { api_key: "secret".to_string() }
);
let name = exchange_config!(config; (Exchange, cfg) => {
// Inside this block:
// - Exchange is the concrete type (exchanges::Binance)
// - cfg is the configuration instance (BinanceConfig)
use exchanges::ExchangeApi;
Exchange::new(cfg).name()
});See the crate documentation and examples for more details.
Derive Macros§
- Concrete
- A derive macro that implements the mapping between enum variants and concrete types.
- Concrete
Config - A derive macro that implements the mapping between enum variants with associated data and concrete types.