Skip to main content

sails_type_registry/
meta_type.rs

1use core::{
2    any::TypeId,
3    cmp::Ordering,
4    fmt::{Debug, Error as FmtError, Formatter},
5    hash::{Hash, Hasher},
6};
7
8use sails_idl_ast::{Type, TypeDecl};
9
10use crate::registry::{Registry, TypeInfo};
11
12/// Type-erased handle to a concrete [`TypeInfo`] implementation.
13#[derive(Clone, Copy)]
14pub struct MetaType {
15    fn_type_decl: fn(&mut Registry) -> TypeDecl,
16    fn_type_def: fn(&mut Registry) -> Option<Type>,
17    fn_module_path: fn() -> &'static str,
18    type_id: TypeId,
19}
20
21impl MetaType {
22    /// Creates a `MetaType` for `T`.
23    pub const fn new<T>() -> Self
24    where
25        T: TypeInfo + ?Sized,
26    {
27        Self {
28            fn_type_decl: T::type_decl,
29            fn_type_def: T::type_def,
30            fn_module_path: T::module_path,
31            type_id: TypeId::of::<T::Identity>(),
32        }
33    }
34
35    /// Produces the use-site type declaration for the represented type.
36    pub fn type_decl(&self, registry: &mut Registry) -> TypeDecl {
37        (self.fn_type_decl)(registry)
38    }
39
40    /// Produces the stored named definition for the represented type, if any.
41    pub fn type_def(&self, registry: &mut Registry) -> Option<Type> {
42        (self.fn_type_def)(registry)
43    }
44
45    /// Returns the module path associated with the represented named type.
46    pub fn module_path(&self) -> &'static str {
47        (self.fn_module_path)()
48    }
49
50    /// Returns the unique identity of the represented type.
51    pub const fn type_id(&self) -> TypeId {
52        self.type_id
53    }
54}
55
56impl PartialEq for MetaType {
57    fn eq(&self, other: &Self) -> bool {
58        self.type_id == other.type_id
59    }
60}
61
62impl Eq for MetaType {}
63
64impl PartialOrd for MetaType {
65    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
66        Some(self.cmp(other))
67    }
68}
69
70impl Ord for MetaType {
71    fn cmp(&self, other: &Self) -> Ordering {
72        self.type_id.cmp(&other.type_id)
73    }
74}
75
76impl Hash for MetaType {
77    fn hash<H: Hasher>(&self, state: &mut H) {
78        self.type_id.hash(state);
79    }
80}
81
82impl Debug for MetaType {
83    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
84        self.type_id.fmt(f)
85    }
86}