af_core/string/
shared.rs

1// Copyright © 2021 Alexandra Frydl
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use crate::prelude::*;
8
9/// A cheaply cloneable string.
10#[derive(Clone)]
11pub struct SharedString(Inner);
12
13#[derive(Clone)]
14enum Inner {
15  ArcStr(Arc<str>),
16  StaticStr(&'static str),
17}
18
19impl SharedString {
20  /// Returns a reference to this string as a `&str`.
21  pub fn as_str(&self) -> &str {
22    match &self.0 {
23      Inner::ArcStr(value) => value.as_ref(),
24      Inner::StaticStr(value) => value,
25    }
26  }
27}
28
29impl AsRef<str> for SharedString {
30  fn as_ref(&self) -> &str {
31    self.as_str()
32  }
33}
34
35impl Display for SharedString {
36  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37    Display::fmt(self.as_str(), f)
38  }
39}
40
41impl Debug for SharedString {
42  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43    Debug::fmt(self.as_str(), f)
44  }
45}
46
47impl Default for SharedString {
48  fn default() -> Self {
49    Self(Inner::StaticStr(""))
50  }
51}
52
53impl Deref for SharedString {
54  type Target = str;
55
56  fn deref(&self) -> &Self::Target {
57    self.as_str()
58  }
59}
60
61impl<'de> Deserialize<'de> for SharedString {
62  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
63  where
64    D: Deserializer<'de>,
65  {
66    String::deserialize(deserializer).map(SharedString::from)
67  }
68}
69
70impl From<&'static str> for SharedString {
71  fn from(value: &'static str) -> Self {
72    Self(Inner::StaticStr(value))
73  }
74}
75
76impl From<Arc<str>> for SharedString {
77  fn from(value: Arc<str>) -> Self {
78    Self(Inner::ArcStr(value))
79  }
80}
81
82impl From<String> for SharedString {
83  fn from(value: String) -> Self {
84    Self(Inner::ArcStr(value.into()))
85  }
86}
87
88impl From<Cow<'static, str>> for SharedString {
89  fn from(value: Cow<'static, str>) -> Self {
90    match value {
91      Cow::Borrowed(value) => Self(Inner::StaticStr(value)),
92      Cow::Owned(value) => Self(Inner::ArcStr(value.into())),
93    }
94  }
95}
96
97impl Eq for SharedString {}
98
99impl Hash for SharedString {
100  fn hash<H: Hasher>(&self, state: &mut H) {
101    self.as_str().hash(state)
102  }
103}
104
105impl Ord for SharedString {
106  fn cmp(&self, other: &Self) -> cmp::Ordering {
107    self.as_str().cmp(other.as_str())
108  }
109}
110
111impl PartialEq for SharedString {
112  fn eq(&self, other: &Self) -> bool {
113    self.as_str() == other.as_str()
114  }
115}
116
117impl PartialOrd for SharedString {
118  fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
119    self.as_str().partial_cmp(other.as_str())
120  }
121}
122
123impl Serialize for SharedString {
124  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
125  where
126    S: serde::Serializer,
127  {
128    self.as_str().serialize(serializer)
129  }
130}