substrate_data/schema/refs/
kind.rs1use super::RefId;
4use crate::model::value::KindName;
5
6pub trait Kind {
10 const NAME: &'static str;
13 type Id: RefId;
15
16 #[must_use]
18 fn kind_name() -> KindName {
19 KindName::declared(Self::NAME)
20 }
21}
22
23pub trait Kinds {
26 const NAMES: &'static [&'static str];
28 type Id: RefId;
30
31 #[must_use]
33 fn first() -> KindName {
34 KindName::declared(Self::NAMES.first().copied().unwrap_or_default())
35 }
36}
37
38impl<K: Kind> Kinds for K {
39 const NAMES: &'static [&'static str] = &[K::NAME];
40 type Id = K::Id;
41}
42
43impl<A: Kind, B: Kind<Id = A::Id>> Kinds for (A, B) {
44 const NAMES: &'static [&'static str] = &[A::NAME, B::NAME];
45 type Id = A::Id;
46}
47
48impl<A: Kind, B: Kind<Id = A::Id>, C: Kind<Id = A::Id>> Kinds for (A, B, C) {
49 const NAMES: &'static [&'static str] = &[A::NAME, B::NAME, C::NAME];
50 type Id = A::Id;
51}
52
53#[macro_export]
68macro_rules! kind {
69 () => {};
70 ($name:ident = $kind:literal $(: $id:ty)? $(, $($rest:tt)*)?) => {
71 $crate::__kind_item!($name, concat!("The `", $kind, "` kind of reference."), $kind, $($id)?);
72 $crate::kind!($($($rest)*)?);
73 };
74 ($name:ident = $kind:path $(: $id:ty)? $(, $($rest:tt)*)?) => {
75 $crate::__kind_item!(
76 $name,
77 concat!("The kind named by `", stringify!($kind), "`."),
78 $kind,
79 $($id)?
80 );
81 $crate::kind!($($($rest)*)?);
82 };
83 ($name:ident = $kind:block $(: $id:ty)? $(, $($rest:tt)*)?) => {
84 $crate::__kind_item!($name, "A kind of reference.", $kind, $($id)?);
85 $crate::kind!($($($rest)*)?);
86 };
87}
88
89#[doc(hidden)]
90#[macro_export]
91macro_rules! __kind_item {
92 ($name:ident, $doc:expr, $kind:expr, $($id:ty)?) => {
93 #[doc = $doc]
94 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
95 pub struct $name;
96 impl $crate::Kind for $name {
97 const NAME: &'static str = $kind;
98 type Id = $crate::__id_or_string!($($id)?);
99 }
100 const _: () = assert!(
102 $crate::KindName::is_valid(<$name as $crate::Kind>::NAME),
103 "a kind is lower case letters, digits and `_`, starting with a letter"
104 );
105 };
106}
107
108#[doc(hidden)]
109#[macro_export]
110macro_rules! __id_or_string {
111 () => {
112 ::std::string::String
113 };
114 ($id:ty) => {
115 $id
116 };
117}