laburnum 1.17.1

An LSP framework for building language servers and compilers, powered by an incremental query tree with content-addressed storage, task-based dataflow, and parallel queries.
Documentation
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

/// Declares a set of known identifiers as compile-time constants.
///
/// This macro generates `pub const` declarations for [`Ident`] values and a
/// `try_resolve` function to look up the original string from an ident hash.
///
/// # Usage
///
/// Create a dedicated `{language}-known-idents` crate for your language's
/// known identifiers. This keeps them centralized and allows both the compiler
/// and LSP to share the same definitions.
///
/// ```ignore
/// // In your {language}-known-idents/src/lib.rs
/// use laburnum::known_idents;
///
/// known_idents! {
///     // Simple identifiers: input becomes the string value,
///     // UPPER_CASE version becomes the const name
///     theme,           // pub const THEME: Ident = Ident::new("theme");
///     palette,         // pub const PALETTE: Ident = Ident::new("palette");
///     my_field,        // pub const MY_FIELD: Ident = Ident::new("my_field");
///
///     // Explicit overrides for strings that aren't valid Rust identifiers
///     // or need different const names (e.g., PascalCase, kebab-case)
///     {
///         COLOR_HEX = "ColorHex",
///         TEMPLATES_PER_VARIANT = "templates-per-variant",
///     }
/// }
/// ```
///
/// # Generated Code
///
/// The macro generates:
/// - `pub const NAME: Ident` for each identifier
/// - `pub fn try_resolve(ident: Ident) -> Option<&'static str>` to look up strings
///
/// # Crate Structure
///
/// Recommended structure for a language called "mylang":
///
/// ```text
/// crates/
///   mylang-known-idents/
///     Cargo.toml
///     src/lib.rs        # known_idents! { ... }
/// ```
///
/// Your `Cargo.toml` must include both `laburnum` and `paste`:
///
/// ```toml
/// [dependencies]
/// laburnum = { workspace = true }
/// paste = { workspace = true }
/// ```
///
/// Then depend on `mylang-known-idents` from your compiler and LSP crates.
#[macro_export]
macro_rules! known_idents {
    (
        $( $name:ident ),* $(,)?
        $(
            { $( $const_name:ident = $string:literal ),+ $(,)? }
        )?
    ) => {
        ::paste::paste! {
            $(
                pub const [<$name:upper>]: $crate::Ident = $crate::Ident::new(stringify!($name));
            )*
            $(
                $(
                    pub const $const_name: $crate::Ident = $crate::Ident::new($string);
                )+
            )?

            pub fn try_resolve(ident: $crate::Ident) -> Option<&'static str> {
                match ident {
                    $(
                        _ if ident == [<$name:upper>] => Some(stringify!($name)),
                    )*
                    $(
                        $(
                            _ if ident == $const_name => Some($string),
                        )+
                    )?
                    _ => None,
                }
            }
        }
    };
}