3个不稳定版本
0.2.0 | 2024年5月26日 |
---|---|
0.1.1 | 2024年5月18日 |
0.1.0 | 2024年5月2日 |
#350 in 内存管理
每月 166 次下载
28KB
477 行
type-registry
Rust中类型的静态注册。
lib.rs
:
用于静态注册类型的库。
例如:
use type_registry::{registration, Registered, Registration, Registry, RegistryExt};
struct StringAnalyserTypeInfo {
analyse: fn(&str) -> Option<usize>
}
struct StringAnalyserRegistry;
impl Registry for StringAnalyserRegistry {
type TypeInfo = StringAnalyserTypeInfo;
fn name() -> &'static str {
"String Analysers"
}
}
struct LenAnalyser;
unsafe impl Registered<StringAnalyserRegistry> for LenAnalyser {
fn register() -> Registration<StringAnalyserRegistry, Self> {
// NOTE: Can't use generic 'Self' type here
registration!(StringAnalyserRegistry, LenAnalyser)
}
fn type_info() -> &'static StringAnalyserTypeInfo {
static TYPE_INFO: StringAnalyserTypeInfo = StringAnalyserTypeInfo {
analyse: |string| Some(string.len())
};
&TYPE_INFO
}
}
struct NumFinderAnalyser;
unsafe impl Registered<StringAnalyserRegistry> for NumFinderAnalyser {
fn register() -> Registration<StringAnalyserRegistry, Self> {
// NOTE: Can't use generic 'Self' type here
registration!(StringAnalyserRegistry, NumFinderAnalyser)
}
fn type_info() -> &'static StringAnalyserTypeInfo {
fn is_digit(c: char) -> bool {
c.is_ascii_digit()
}
static TYPE_INFO: StringAnalyserTypeInfo = StringAnalyserTypeInfo {
analyse: |string| {
let start = string.find(is_digit)?;
let end = string.rfind(is_digit)?;
std::str::FromStr::from_str(&string[start..=end]).ok()
}
};
&TYPE_INFO
}
}
fn main() {
for (_id, entry) in StringAnalyserRegistry::iter() {
assert_eq!((entry.type_info().analyse)("I'm 22 characters long"), Some(22))
}
}
如果您希望注册表中的所有类型都实现某些特性,您可以通过仅使类型-info对实现该特性的类型可构造来静态确保这一点。此外,如果您要求所有特性的实现者都进行注册,您可以为特性添加[Registered]界限。
例如,类似于上面的示例,但有一个StringAnalyser特性
use type_registry::{register, Registered, Registration, Registry, RegistryExt};
trait StringAnalyser: Registered<StringAnalyserRegistry> {
fn analyse(string: &str) -> Option<usize>;
}
struct StringAnalyserTypeInfo {
analyse: fn(&str) -> Option<usize>
}
impl StringAnalyserTypeInfo {
pub const fn new<T: StringAnalyser>() -> Self {
Self {
analyse: T::analyse
}
}
}
struct StringAnalyserRegistry;
impl Registry for StringAnalyserRegistry {
type TypeInfo = StringAnalyserTypeInfo;
fn name() -> &'static str {
"String Analysers"
}
}
#[register(StringAnalyserRegistry)]
struct LenAnalyser;
impl StringAnalyser for LenAnalyser {
fn analyse(string: &str) -> Option<usize> {
Some(string.len())
}
}
#[register(StringAnalyserRegistry)]
struct NumFinderAnalyser;
impl NumFinderAnalyser {
fn is_digit(c: char) -> bool {
c.is_ascii_digit()
}
}
impl StringAnalyser for NumFinderAnalyser {
fn analyse(string: &str) -> Option<usize> {
let start = string.find(Self::is_digit)?;
let end = string.rfind(Self::is_digit)?;
std::str::FromStr::from_str(&string[start..=end]).ok()
}
}
fn main() {
for (_id, entry) in StringAnalyserRegistry::iter() {
assert_eq!((entry.type_info().analyse)("I'm 22 characters long"), Some(22))
}
}
依赖项
~325–800KB
~18K SLoC