derive_deftly_macros/
general_context.rs1use super::framework::*;
4
5use GeneralContext as GC;
6use GeneralContextBuf as GCB;
7
8pub type FullContextResult<'s, 'c> = Result<
11 &'s Context<'c>, MissingContextError<'c>,
13>;
14
15#[derive(Clone, Copy)]
21pub struct MissingContextError<'c> {
22 span: Span,
23 error_handler: ErrorGenerator<'c>,
24}
25
26#[derive(Clone, Copy)]
30pub enum GeneralContext<'c> {
31 Full(&'c Context<'c>),
32 NoDriver(&'c DriverlessContext<'c>),
33}
34
35#[derive(Clone, Copy)]
39pub enum GeneralContextBuf<'c> {
40 Full(Context<'c>),
41 NoDriver(DriverlessContext<'c>),
42}
43
44#[derive(Clone, Copy)]
45pub struct DriverlessContext<'c> {
46 pub defs: DefinitionsContext<'c>,
47 pub driver_needed: ErrorGenerator<'c>,
48}
49
50impl<'c> GeneralContext<'c> {
53 pub fn full_ctx_raw(&self) -> Result<&Context<'c>, ErrorGenerator<'c>> {
54 match self {
55 GC::Full(ctx) => Ok(ctx),
56 GC::NoDriver(dc) => Err(dc.driver_needed),
57 }
58 }
59
60 pub fn full_ctx(&self, span: Span) -> FullContextResult<'_, 'c> {
62 self.full_ctx_raw()
63 .map_err(move |error_handler| MissingContextError {
64 span,
65 error_handler,
66 })
67 }
68
69 pub fn defs(&self) -> &DefinitionsContext<'c> {
76 self.as_ref()
77 }
78
79 pub fn error_loc(&self) -> Option<ErrorLoc<'c>> {
80 match self {
81 GC::Full(ctx) => Some(ctx.error_loc()),
82 GC::NoDriver { .. } => None,
83 }
84 }
85
86 pub fn prepend_error_loc(
87 &self,
88 rest: &'_ [ErrorLoc<'c>],
89 ) -> Vec<ErrorLoc<'c>> {
90 chain!(
91 self.error_loc(), rest.iter().copied(),
93 )
94 .collect_vec()
95 }
96
97 pub fn clone_buf(&self) -> GeneralContextBuf<'c> {
98 match self {
99 GC::Full(ctx) => GCB::Full((*ctx).clone()),
100 GC::NoDriver(dc) => GCB::NoDriver((*dc).clone()),
101 }
102 }
103}
104
105impl<'c> AsRef<DefinitionsContext<'c>> for GeneralContext<'c> {
106 fn as_ref(&self) -> &DefinitionsContext<'c> {
107 match self {
108 GC::Full(ctx) => &ctx.defs,
109 GC::NoDriver(dc) => &dc.defs,
110 }
111 }
112}
113
114impl<'c> AsMut<DefinitionsContext<'c>> for GeneralContextBuf<'c> {
115 fn as_mut(&mut self) -> &mut DefinitionsContext<'c> {
116 match self {
117 GCB::Full(ctx) => &mut ctx.defs,
118 GCB::NoDriver(dc) => &mut dc.defs,
119 }
120 }
121}
122
123struct ContextDbgDisplayAdapter<'a>(Option<&'a Context<'a>>);
126
127impl Display for ContextDbgDisplayAdapter<'_> {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 let ctx = match self.0 {
130 Some(y) => y,
131 None => return write!(f, "[no driver]"),
132 };
133
134 write!(f, "for {}", &ctx.top.ident)?;
135 if let Some(wv) = &ctx.variant {
136 if let Some(v) = &wv.variant {
137 write!(f, "::{}", &v.ident)?;
138 }
139 }
140 if let Some(wf) = &ctx.field {
141 let span = Span::call_site();
143 write!(f, ".{}", &wf.fname(span))?;
144 }
145 if let Some(templ) = &ctx.template_name {
146 let templ = templ.to_token_stream().to_string();
147 write!(f, " from {}", templ)?;
148 }
149 Ok::<_, fmt::Error>(())
150 }
151}
152
153impl<'c> Context<'c> {
154 pub fn display_for_dbg(&self) -> impl Display + '_ {
155 ContextDbgDisplayAdapter(Some(self))
156 }
157}
158
159impl<'c> GeneralContext<'c> {
160 pub fn display_for_dbg(&self) -> impl Display + '_ {
161 ContextDbgDisplayAdapter(match &self {
162 GC::Full(ctx) => Some(ctx),
163 GC::NoDriver { .. } => None,
164 })
165 }
166}
167
168impl<'c> Context<'c> {
171 pub fn as_general(&'c self) -> GeneralContext<'c> {
172 GC::Full(self)
173 }
174}
175
176impl<'c> GeneralContextBuf<'c> {
177 pub fn as_ref(&'c self) -> GeneralContext<'c> {
178 match self {
179 GCB::Full(ctx) => GC::Full(ctx),
180 GCB::NoDriver(dc) => GC::NoDriver(dc),
181 }
182 }
183}
184
185impl<'c> From<MissingContextError<'c>> for syn::Error {
188 fn from(e: MissingContextError<'c>) -> syn::Error {
189 (e.error_handler)(e.span)
190 }
191}