substrate_data/schema/
fields.rs1pub trait Fields {
8 const FIELDS: &'static [(&'static str, &'static str)];
10}
11
12#[must_use]
20#[expect(
21 clippy::panic,
22 reason = "a panic in a constant is the compile error `field!` gives"
23)]
24pub const fn field_name(
25 fields: &'static [(&'static str, &'static str)],
26 ident: &str,
27) -> &'static str {
28 let mut i = 0;
29 while i < fields.len() {
30 if same(fields[i].0, ident) {
31 return fields[i].1;
32 }
33 i += 1;
34 }
35 panic!("no such field")
36}
37
38const fn same(a: &str, b: &str) -> bool {
39 let (a, b) = (a.as_bytes(), b.as_bytes());
40 if a.len() != b.len() {
41 return false;
42 }
43 let mut i = 0;
44 while i < a.len() {
45 if a[i] != b[i] {
46 return false;
47 }
48 i += 1;
49 }
50 true
51}
52
53#[macro_export]
56macro_rules! field {
57 ($t:ty, $f:ident) => {{
58 const NAME: &str = $crate::schema::field_name(
59 <$t as $crate::schema::Fields>::FIELDS,
60 ::core::stringify!($f),
61 );
62 NAME
63 }};
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::Schema;
69
70 #[derive(Schema)]
71 struct Probe {
72 plain: u32,
73 #[data(rename = "written")]
74 renamed: u32,
75 }
76
77 #[test]
78 fn fields_by_their_rust_names() {
79 assert_eq!(crate::field!(Probe, plain), "plain");
80 assert_eq!(crate::field!(Probe, renamed), "written");
81 }
82}