Line data Source code
1 : use crate::intern::{EndpointIdInt, EndpointIdTag, InternId};
2 :
3 : macro_rules! smol_str_wrapper {
4 : ($name:ident) => {
5 : #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
6 : pub struct $name(smol_str::SmolStr);
7 :
8 : impl $name {
9 : #[allow(unused)]
10 0 : pub(crate) fn as_str(&self) -> &str {
11 0 : self.0.as_str()
12 0 : }
13 : }
14 :
15 : impl std::fmt::Display for $name {
16 3 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 3 : self.0.fmt(f)
18 3 : }
19 : }
20 :
21 : impl<T> std::cmp::PartialEq<T> for $name
22 : where
23 : smol_str::SmolStr: std::cmp::PartialEq<T>,
24 : {
25 19 : fn eq(&self, other: &T) -> bool {
26 19 : self.0.eq(other)
27 19 : }
28 : }
29 :
30 : impl<T> From<T> for $name
31 : where
32 : smol_str::SmolStr: From<T>,
33 : {
34 166 : fn from(x: T) -> Self {
35 166 : Self(x.into())
36 166 : }
37 : }
38 :
39 : impl AsRef<str> for $name {
40 10 : fn as_ref(&self) -> &str {
41 10 : self.0.as_ref()
42 10 : }
43 : }
44 :
45 : impl std::ops::Deref for $name {
46 : type Target = str;
47 167 : fn deref(&self) -> &str {
48 167 : &*self.0
49 167 : }
50 : }
51 :
52 : impl<'de> serde::de::Deserialize<'de> for $name {
53 0 : fn deserialize<D: serde::de::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
54 0 : <smol_str::SmolStr as serde::de::Deserialize<'de>>::deserialize(d).map(Self)
55 0 : }
56 : }
57 :
58 : impl serde::Serialize for $name {
59 0 : fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
60 0 : self.0.serialize(s)
61 0 : }
62 : }
63 : };
64 : }
65 :
66 : const POOLER_SUFFIX: &str = "-pooler";
67 :
68 : impl EndpointId {
69 : #[must_use]
70 3 : pub fn normalize(&self) -> Self {
71 3 : if let Some(stripped) = self.as_ref().strip_suffix(POOLER_SUFFIX) {
72 0 : stripped.into()
73 : } else {
74 3 : self.clone()
75 : }
76 3 : }
77 :
78 : #[must_use]
79 0 : pub fn normalize_intern(&self) -> EndpointIdInt {
80 0 : if let Some(stripped) = self.as_ref().strip_suffix(POOLER_SUFFIX) {
81 0 : EndpointIdTag::get_interner().get_or_intern(stripped)
82 : } else {
83 0 : self.into()
84 : }
85 0 : }
86 : }
87 :
88 : // 90% of role name strings are 20 characters or less.
89 : smol_str_wrapper!(RoleName);
90 : // 50% of endpoint strings are 23 characters or less.
91 : smol_str_wrapper!(EndpointId);
92 : // 50% of branch strings are 23 characters or less.
93 : smol_str_wrapper!(BranchId);
94 : // 90% of project strings are 23 characters or less.
95 : smol_str_wrapper!(ProjectId);
96 :
97 : // will usually equal endpoint ID
98 : smol_str_wrapper!(EndpointCacheKey);
99 :
100 : smol_str_wrapper!(DbName);
101 :
102 : // postgres hostname, will likely be a port:ip addr
103 : smol_str_wrapper!(Host);
104 :
105 : // Endpoints are a bit tricky. Rare they might be branches or projects.
106 : impl EndpointId {
107 0 : pub(crate) fn is_endpoint(&self) -> bool {
108 0 : self.0.starts_with("ep-")
109 0 : }
110 0 : pub(crate) fn is_branch(&self) -> bool {
111 0 : self.0.starts_with("br-")
112 0 : }
113 : // pub(crate) fn is_project(&self) -> bool {
114 : // !self.is_endpoint() && !self.is_branch()
115 : // }
116 0 : pub(crate) fn as_branch(&self) -> BranchId {
117 0 : BranchId(self.0.clone())
118 0 : }
119 0 : pub(crate) fn as_project(&self) -> ProjectId {
120 0 : ProjectId(self.0.clone())
121 0 : }
122 : }
|