flams_utils/
id_counters.rs1use std::{borrow::Cow, collections::hash_map::Entry, fmt::Display};
2
3use crate::prelude::HMap;
4
5#[derive(Clone, Debug, PartialEq, Eq, Hash)]
6pub enum CowStr {
7 Borrowed(&'static str),
8 Owned(Box<str>),
9}
10impl std::ops::Deref for CowStr {
11 type Target = str;
12 #[inline]
13 fn deref(&self) -> &str {
14 match self {
15 Self::Borrowed(s) => s,
16 Self::Owned(s) => s,
17 }
18 }
19}
20impl AsRef<str> for CowStr {
21 #[inline]
22 fn as_ref(&self) -> &str {
23 &**self
24 }
25}
26
27impl From<&'static str> for CowStr {
28 #[inline]
29 fn from(s: &'static str) -> Self {
30 Self::Borrowed(s)
31 }
32}
33impl From<String> for CowStr {
34 #[inline]
35 fn from(s: String) -> Self {
36 Self::Owned(s.into_boxed_str())
37 }
38}
39impl From<Box<str>> for CowStr {
40 #[inline]
41 fn from(s: Box<str>) -> Self {
42 Self::Owned(s)
43 }
44}
45impl From<Cow<'static, str>> for CowStr {
46 #[inline]
47 fn from(s: Cow<'static, str>) -> Self {
48 match s {
49 Cow::Borrowed(s) => Self::Borrowed(s),
50 Cow::Owned(s) => Self::Owned(s.into_boxed_str()),
51 }
52 }
53}
54
55impl Display for CowStr {
56 #[inline]
57 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
58 self.as_ref().fmt(f)
59 }
60}
61
62#[derive(Clone, Debug)]
63pub struct IdCounter {
64 inner: HMap<CowStr, u32>,
65}
66impl Default for IdCounter {
67 fn default() -> Self {
68 let mut inner = HMap::default();
69 inner.insert("EXTSTRUCT".into(), 0);
70 Self { inner }
71 }
72}
73impl IdCounter {
74 pub fn new_id(&mut self, prefix: impl Into<CowStr>) -> Box<str> {
75 let prefix = prefix.into();
76 let r = match self.inner.entry(prefix) {
77 Entry::Occupied(mut e) => {
78 *e.get_mut() += 1;
79 format!("{}_{}", e.key(), e.get())
80 }
81 Entry::Vacant(e) => {
82 let r = e.key().to_string();
83 e.insert(0);
84 r
85 }
86 };
87 r.into_boxed_str()
88 }
89}