Skip to main content

rune/compile/
meta_info.rs

1use core::fmt;
2
3use crate::alloc;
4use crate::alloc::prelude::*;
5use crate::compile::meta;
6use crate::{Hash, Item, ItemBuf};
7
8/// Provides an owned human-readable description of a meta item.
9#[derive(Debug)]
10#[non_exhaustive]
11pub struct MetaInfo {
12    /// The kind of the item.
13    kind: MetaInfoKind,
14    /// The hash of the meta item.
15    hash: Hash,
16    /// The item being described.
17    item: Option<ItemBuf>,
18}
19
20impl MetaInfo {
21    /// Construct a new meta info.
22    pub(crate) fn new(kind: &meta::Kind, hash: Hash, item: Option<&Item>) -> alloc::Result<Self> {
23        Ok(Self {
24            kind: MetaInfoKind::from_kind(kind),
25            hash,
26            item: item.map(|item| item.try_to_owned()).transpose()?,
27        })
28    }
29}
30
31impl fmt::Display for MetaInfo {
32    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
33        struct Name<'a>(Hash, Option<&'a Item>);
34
35        impl fmt::Display for Name<'_> {
36            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37                if let Some(item) = self.1 {
38                    item.fmt(f)
39                } else {
40                    self.0.fmt(f)
41                }
42            }
43        }
44
45        let name = Name(self.hash, self.item.as_deref());
46
47        match self.kind {
48            MetaInfoKind::Type => {
49                write!(fmt, "type {name}")?;
50            }
51            MetaInfoKind::Struct => {
52                write!(fmt, "struct {name}")?;
53            }
54            MetaInfoKind::Variant => {
55                write!(fmt, "variant {name}")?;
56            }
57            MetaInfoKind::Enum => {
58                write!(fmt, "enum {name}")?;
59            }
60            MetaInfoKind::Macro => {
61                write!(fmt, "macro {name}")?;
62            }
63            MetaInfoKind::AttributeMacro => {
64                write!(fmt, "attribute macro {name}")?;
65            }
66            MetaInfoKind::Function => {
67                write!(fmt, "fn {name}")?;
68            }
69            MetaInfoKind::Associated => {
70                write!(fmt, "associated fn {name}")?;
71            }
72            MetaInfoKind::Closure => {
73                write!(fmt, "closure {name}")?;
74            }
75            MetaInfoKind::AsyncBlock => {
76                write!(fmt, "async block {name}")?;
77            }
78            MetaInfoKind::Const => {
79                write!(fmt, "const {name}")?;
80            }
81            MetaInfoKind::Static => {
82                write!(fmt, "static {name}")?;
83            }
84            MetaInfoKind::ConstFn => {
85                write!(fmt, "const fn {name}")?;
86            }
87            MetaInfoKind::Import => {
88                write!(fmt, "import {name}")?;
89            }
90            MetaInfoKind::Alias => {
91                write!(fmt, "import {name}")?;
92            }
93            MetaInfoKind::Module => {
94                write!(fmt, "module {name}")?;
95            }
96            MetaInfoKind::Trait => {
97                write!(fmt, "trait {name}")?;
98            }
99        }
100
101        Ok(())
102    }
103}
104
105#[derive(Debug, Clone, Copy)]
106pub(crate) enum MetaInfoKind {
107    Type,
108    Struct,
109    Variant,
110    Enum,
111    Macro,
112    AttributeMacro,
113    Function,
114    Associated,
115    Closure,
116    AsyncBlock,
117    Const,
118    Static,
119    ConstFn,
120    Import,
121    Alias,
122    Module,
123    Trait,
124}
125
126impl MetaInfoKind {
127    fn from_kind(value: &meta::Kind) -> Self {
128        match value {
129            meta::Kind::Type { .. } => MetaInfoKind::Type,
130            meta::Kind::Struct {
131                enum_hash: Hash::EMPTY,
132                ..
133            } => MetaInfoKind::Struct,
134            meta::Kind::Struct { .. } => MetaInfoKind::Variant,
135            meta::Kind::Enum { .. } => MetaInfoKind::Enum,
136            meta::Kind::Macro => MetaInfoKind::Macro,
137            meta::Kind::AttributeMacro => MetaInfoKind::AttributeMacro,
138            meta::Kind::Function {
139                associated: None, ..
140            } => MetaInfoKind::Function,
141            meta::Kind::Function {
142                associated: Some(..),
143                ..
144            } => MetaInfoKind::Associated,
145            meta::Kind::Closure { .. } => MetaInfoKind::Closure,
146            meta::Kind::AsyncBlock { .. } => MetaInfoKind::AsyncBlock,
147            meta::Kind::Const => MetaInfoKind::Const,
148            meta::Kind::Static => MetaInfoKind::Static,
149            meta::Kind::ConstFn => MetaInfoKind::ConstFn,
150            meta::Kind::Import { .. } => MetaInfoKind::Import,
151            meta::Kind::Alias { .. } => MetaInfoKind::Alias,
152            meta::Kind::Module => MetaInfoKind::Module,
153            meta::Kind::Trait => MetaInfoKind::Trait,
154        }
155    }
156}