3个不稳定版本

0.2.0 2024年5月26日
0.1.1 2024年5月18日
0.1.0 2024年5月2日

#350 in 内存管理

Download history 169/week @ 2024-04-27 79/week @ 2024-05-04 9/week @ 2024-05-11 213/week @ 2024-05-18 193/week @ 2024-05-25 28/week @ 2024-06-01 29/week @ 2024-06-08 230/week @ 2024-06-15 146/week @ 2024-06-22 89/week @ 2024-06-29 416/week @ 2024-07-06 120/week @ 2024-07-13 55/week @ 2024-07-20 74/week @ 2024-07-27 7/week @ 2024-08-03 17/week @ 2024-08-10

每月 166 次下载

Apache-2.0

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