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]
56macro_rules! kind {
57 ($($name:ident = $kind:literal $(: $id:ty)?),* $(,)?) => {$(
58 #[doc = concat!("The `", $kind, "` kind of reference.")]
59 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
60 pub struct $name;
61 impl $crate::Kind for $name {
62 const NAME: &'static str = {
63 assert!(
64 $crate::KindName::is_valid($kind),
65 "a kind is lower case letters, digits and `_`, starting with a letter"
66 );
67 $kind
68 };
69 type Id = $crate::__id_or_string!($($id)?);
70 }
71 )*};
72}
73
74#[doc(hidden)]
75#[macro_export]
76macro_rules! __id_or_string {
77 () => {
78 ::std::string::String
79 };
80 ($id:ty) => {
81 $id
82 };
83}