Skip to main content

metrique_core/
namestyle.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Contains various name styles
5
6use std::marker::PhantomData;
7
8use crate::concat::{Concatenated, EmptyConstStr, MaybeConstStr};
9
10pub(crate) mod private {
11    /// Helper trait to make `NameStyle` sealed
12    pub trait NameStyleInternal {}
13}
14
15/// This trait is used to describe name styles for [`InflectableEntry`].
16///
17/// The exact implementation of this trait is currently unstable.
18///
19/// [`InflectableEntry`]: crate::InflectableEntry
20pub trait NameStyle: private::NameStyleInternal {
21    #[doc(hidden)]
22    type KebabCase: NameStyle;
23
24    #[doc(hidden)]
25    type PascalCase: NameStyle;
26
27    #[doc(hidden)]
28    type SnakeCase: NameStyle;
29
30    #[doc(hidden)]
31    type AppendPrefix<T: MaybeConstStr>: NameStyle;
32
33    /// Inflect the name, adding prefixes
34    #[doc(hidden)]
35    type Inflect<ID: MaybeConstStr, PASCAL: MaybeConstStr, SNAKE: MaybeConstStr, KEBAB: MaybeConstStr>: MaybeConstStr;
36
37    /// Inflect an affix (just inflect, without adding prefixes)
38    #[doc(hidden)]
39    type InflectAffix<ID: MaybeConstStr, PASCAL: MaybeConstStr, SNAKE: MaybeConstStr, KEBAB: MaybeConstStr>: MaybeConstStr;
40}
41
42/// Inflects names to the identity case
43pub struct Identity<PREFIX: MaybeConstStr = EmptyConstStr>(PhantomData<PREFIX>);
44impl<PREFIX: MaybeConstStr> private::NameStyleInternal for Identity<PREFIX> {}
45impl<PREFIX: MaybeConstStr> NameStyle for Identity<PREFIX> {
46    type KebabCase = KebabCase<PREFIX>;
47    type PascalCase = PascalCase<PREFIX>;
48    type SnakeCase = SnakeCase<PREFIX>;
49    type AppendPrefix<P: MaybeConstStr> = Identity<Concatenated<PREFIX, P>>;
50    type Inflect<
51        ID: MaybeConstStr,
52        PASCAL: MaybeConstStr,
53        SNAKE: MaybeConstStr,
54        KEBAB: MaybeConstStr,
55    > = Concatenated<PREFIX, ID>;
56    type InflectAffix<
57        ID: MaybeConstStr,
58        PASCAL: MaybeConstStr,
59        SNAKE: MaybeConstStr,
60        KEBAB: MaybeConstStr,
61    > = ID;
62}
63
64/// inflects names to `PascalCase`
65pub struct PascalCase<PREFIX: MaybeConstStr = EmptyConstStr>(PhantomData<PREFIX>);
66impl<PREFIX: MaybeConstStr> private::NameStyleInternal for PascalCase<PREFIX> {}
67impl<PREFIX: MaybeConstStr> NameStyle for PascalCase<PREFIX> {
68    type KebabCase = KebabCase<PREFIX>;
69    type PascalCase = PascalCase<PREFIX>;
70    type SnakeCase = SnakeCase<PREFIX>;
71    type AppendPrefix<P: MaybeConstStr> = PascalCase<Concatenated<PREFIX, P>>;
72    type Inflect<
73        ID: MaybeConstStr,
74        PASCAL: MaybeConstStr,
75        SNAKE: MaybeConstStr,
76        KEBAB: MaybeConstStr,
77    > = Concatenated<PREFIX, PASCAL>;
78    type InflectAffix<
79        ID: MaybeConstStr,
80        PASCAL: MaybeConstStr,
81        SNAKE: MaybeConstStr,
82        KEBAB: MaybeConstStr,
83    > = PASCAL;
84}
85
86/// Inflects names to `snake_case`
87pub struct SnakeCase<PREFIX: MaybeConstStr = EmptyConstStr>(PhantomData<PREFIX>);
88impl<PREFIX: MaybeConstStr> private::NameStyleInternal for SnakeCase<PREFIX> {}
89impl<PREFIX: MaybeConstStr> NameStyle for SnakeCase<PREFIX> {
90    type KebabCase = KebabCase<PREFIX>;
91    type PascalCase = PascalCase<PREFIX>;
92    type SnakeCase = SnakeCase<PREFIX>;
93    type AppendPrefix<P: MaybeConstStr> = SnakeCase<Concatenated<PREFIX, P>>;
94    type Inflect<
95        ID: MaybeConstStr,
96        PASCAL: MaybeConstStr,
97        SNAKE: MaybeConstStr,
98        KEBAB: MaybeConstStr,
99    > = Concatenated<PREFIX, SNAKE>;
100    type InflectAffix<
101        ID: MaybeConstStr,
102        PASCAL: MaybeConstStr,
103        SNAKE: MaybeConstStr,
104        KEBAB: MaybeConstStr,
105    > = SNAKE;
106}
107
108/// Inflects names to `kebab-case`
109pub struct KebabCase<PREFIX: MaybeConstStr = EmptyConstStr>(PhantomData<PREFIX>);
110impl<PREFIX: MaybeConstStr> private::NameStyleInternal for KebabCase<PREFIX> {}
111impl<PREFIX: MaybeConstStr> NameStyle for KebabCase<PREFIX> {
112    type KebabCase = KebabCase<PREFIX>;
113    type PascalCase = PascalCase<PREFIX>;
114    type SnakeCase = SnakeCase<PREFIX>;
115    type AppendPrefix<P: MaybeConstStr> = KebabCase<Concatenated<PREFIX, P>>;
116    type Inflect<
117        ID: MaybeConstStr,
118        PASCAL: MaybeConstStr,
119        SNAKE: MaybeConstStr,
120        KEBAB: MaybeConstStr,
121    > = Concatenated<PREFIX, KEBAB>;
122    type InflectAffix<
123        ID: MaybeConstStr,
124        PASCAL: MaybeConstStr,
125        SNAKE: MaybeConstStr,
126        KEBAB: MaybeConstStr,
127    > = KEBAB;
128}
129
130/// Runtime-selectable name style for metric field names.
131///
132/// This mirrors the compile-time [`NameStyle`] types (`Identity`, `PascalCase`,
133/// etc.) as enum variants for use in runtime configuration.
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
135#[non_exhaustive]
136pub enum DynamicNameStyle {
137    /// Keep original field names.
138    #[default]
139    Identity,
140    /// Convert to PascalCase (e.g. `WorkersCount`).
141    PascalCase,
142    /// Convert to snake_case (e.g. `workers_count`).
143    SnakeCase,
144    /// Convert to kebab-case (e.g. `workers-count`).
145    KebabCase,
146}