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 180 : fn from(x: T) -> Self {
35 180 : Self(x.into())
36 180 : }
37 : }
38 :
39 : impl AsRef<str> for $name {
40 13 : fn as_ref(&self) -> &str {
41 13 : self.0.as_ref()
42 13 : }
43 : }
44 :
45 : impl std::ops::Deref for $name {
46 : type Target = str;
47 181 : fn deref(&self) -> &str {
48 181 : &*self.0
49 181 : }
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 : pub(crate) const LOCAL_PROXY_SUFFIX: &str = "-local-proxy";
68 :
69 : impl EndpointId {
70 : #[must_use]
71 3 : fn normalize_str(&self) -> &str {
72 3 : if let Some(stripped) = self.as_ref().strip_suffix(POOLER_SUFFIX) {
73 0 : stripped
74 3 : } else if let Some(stripped) = self.as_ref().strip_suffix(LOCAL_PROXY_SUFFIX) {
75 0 : stripped
76 : } else {
77 3 : self
78 : }
79 3 : }
80 :
81 : #[must_use]
82 3 : pub fn normalize(&self) -> Self {
83 3 : self.normalize_str().into()
84 3 : }
85 :
86 : #[must_use]
87 0 : pub fn normalize_intern(&self) -> EndpointIdInt {
88 0 : EndpointIdTag::get_interner().get_or_intern(self.normalize_str())
89 0 : }
90 : }
91 :
92 : // 90% of role name strings are 20 characters or less.
93 : smol_str_wrapper!(RoleName);
94 : // 50% of endpoint strings are 23 characters or less.
95 : smol_str_wrapper!(EndpointId);
96 : // 50% of branch strings are 23 characters or less.
97 : smol_str_wrapper!(BranchId);
98 : // 90% of project strings are 23 characters or less.
99 : smol_str_wrapper!(ProjectId);
100 :
101 : // will usually equal endpoint ID
102 : smol_str_wrapper!(EndpointCacheKey);
103 :
104 : smol_str_wrapper!(DbName);
105 :
106 : // postgres hostname, will likely be a port:ip addr
107 : smol_str_wrapper!(Host);
108 :
109 : // Endpoints are a bit tricky. Rare they might be branches or projects.
110 : impl EndpointId {
111 0 : pub(crate) fn is_endpoint(&self) -> bool {
112 0 : self.0.starts_with("ep-")
113 0 : }
114 0 : pub(crate) fn is_branch(&self) -> bool {
115 0 : self.0.starts_with("br-")
116 0 : }
117 : }
|