1use serde::Deserialize;
2use std::any::TypeId;
3use std::collections::HashMap;
4use std::fs;
5use std::path::Path;
6
7#[derive(Debug, Clone, Deserialize)]
8pub struct TypeInfo {
9 pub name: String,
10 pub kind: String,
11 pub fields: Vec<FieldInfo>,
12 pub methods: Vec<MethodInfo>,
13 pub traits: Vec<String>,
14}
15
16#[derive(Debug, Clone, Deserialize)]
17pub struct FieldInfo {
18 pub name: String,
19 pub ty: String,
20}
21
22#[derive(Debug, Clone, Deserialize)]
23pub struct MethodInfo {
24 pub name: String,
25 pub signature: String,
26}
27
28#[derive(Debug, Deserialize)]
29struct TypeRegistryRaw {
30 types: HashMap<String, TypeInfo>,
31}
32
33#[derive(Debug)]
38pub struct Registry {
39 by_name: HashMap<String, TypeInfo>,
41 type_ids: HashMap<TypeId, String>,
43}
44
45impl Registry {
46 pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
48 let content = fs::read_to_string(path)?;
49 let raw: TypeRegistryRaw = serde_json::from_str(&content)?;
50
51 let by_name: HashMap<String, TypeInfo> = raw
52 .types
53 .into_iter()
54 .map(|(_, info)| (info.name.clone(), info))
55 .collect();
56
57 Ok(Registry {
58 by_name,
59 type_ids: HashMap::new(),
60 })
61 }
62
63 pub fn register<T: 'static>(&mut self, type_name: &str) {
68 self.type_ids.insert(TypeId::of::<T>(), type_name.to_string());
69 }
70
71 pub fn get<T: 'static>(&self) -> Option<&TypeInfo> {
75 let type_id = TypeId::of::<T>();
76 let name = self.type_ids.get(&type_id)?;
77 self.by_name.get(name)
78 }
79
80 pub fn get_by_name(&self, name: &str) -> Option<&TypeInfo> {
82 self.by_name.get(name)
83 }
84
85 pub fn type_names(&self) -> impl Iterator<Item = &str> {
87 self.by_name.keys().map(|s| s.as_str())
88 }
89}