1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Global registry of type specs via inventory.
//!
//! Each type that implements [`ElicitSpec`](crate::ElicitSpec) submits a
//! [`TypeSpecInventoryKey`] at compile time. The [`lookup_type_spec`] function
//! searches the registry at runtime by type name; [`lookup_type_spec_by_id`]
//! searches by [`TypeId`] for use in composed specs generated by `#[derive(Elicit)]`.
use TypeId;
use crateTypeSpec;
/// Registration key for the global type spec inventory.
///
/// Submit one of these for each type that implements [`ElicitSpec`](crate::ElicitSpec).
/// The `type_name` must be a string literal (`&'static str`) because
/// `inventory::submit!` requires const-constructible values.
///
/// ```rust,ignore
/// inventory::submit!(TypeSpecInventoryKey::new(
/// "I32Positive",
/// <I32Positive as ElicitSpec>::type_spec,
/// TypeId::of::<I32Positive>,
/// ));
/// ```
collect!;
/// Look up the spec for a type by name.
///
/// Returns `None` if no [`TypeSpecInventoryKey`] has been submitted for that name.
///
/// # Example
///
/// ```rust,ignore
/// if let Some(spec) = lookup_type_spec("I32Positive") {
/// println!("{}: {}", spec.type_name(), spec.summary());
/// }
/// ```
/// Look up the spec for a type by its [`TypeId`].
///
/// This is the mechanism used by composed specs (generated by `#[derive(Elicit)]`)
/// to harvest field-type specs at runtime without requiring `specialization`.
/// Returns `None` if the type has no registered [`ElicitSpec`].
///
/// # Example
///
/// ```rust,ignore
/// // Composed spec harvests field specs at runtime
/// if let Some(field_spec) = lookup_type_spec_by_id(TypeId::of::<I32Positive>()) {
/// // include field_spec entries under "fields.count"
/// }
/// ```