scope.rs

 1// Copyright (c) 2024 Jonas Schäfer <jonas@zombofant.net>
 2//
 3// This Source Code Form is subject to the terms of the Mozilla Public
 4// License, v. 2.0. If a copy of the MPL was not distributed with this
 5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 6
 7//! Identifiers used within generated code.
 8
 9use proc_macro2::Span;
10use syn::*;
11
12/// Container struct for various identifiers used throughout the parser code.
13///
14/// This struct is passed around from the [`crate::compound::Compound`]
15/// downward to the code generators in order to ensure that everyone is on the
16/// same page about which identifiers are used for what.
17///
18/// The recommended usage is to bind the names which are needed into the local
19/// scope like this:
20///
21/// ```text
22/// # let scope = FromEventsScope::new();
23/// let FromEventsScope {
24///     ref attrs,
25///     ..
26/// } = scope;
27/// ```
28pub(crate) struct FromEventsScope {
29    /// Accesses the `AttrMap` from code in
30    /// [`crate::field::FieldBuilderPart::Init`].
31    pub(crate) attrs: Ident,
32}
33
34impl FromEventsScope {
35    /// Create a fresh scope with all necessary identifiers.
36    pub(crate) fn new() -> Self {
37        // Sadly, `Ident::new` is not `const`, so we have to create even the
38        // well-known identifiers from scratch all the time.
39        Self {
40            attrs: Ident::new("attrs", Span::call_site()),
41        }
42    }
43}
44
45/// Container struct for various identifiers used throughout the generator
46/// code.
47///
48/// This struct is passed around from the [`crate::compound::Compound`]
49/// downward to the code generators in order to ensure that everyone is on the
50/// same page about which identifiers are used for what.
51///
52/// See [`FromEventsScope`] for recommendations on the usage.
53pub(crate) struct IntoEventsScope {
54    /// Accesses the `AttrMap` from code in
55    /// [`crate::field::FieldIteratorPart::Header`].
56    pub(crate) attrs: Ident,
57}
58
59impl IntoEventsScope {
60    /// Create a fresh scope with all necessary identifiers.
61    pub(crate) fn new() -> Self {
62        Self {
63            attrs: Ident::new("attrs", Span::call_site()),
64        }
65    }
66}
67
68pub(crate) fn mangle_member(member: &Member) -> Ident {
69    match member {
70        Member::Named(member) => quote::format_ident!("f{}", member),
71        Member::Unnamed(member) => quote::format_ident!("f_u{}", member.index),
72    }
73}