shared_string.rs

  1use derive_more::{Deref, DerefMut};
  2
  3use schemars::JsonSchema;
  4use serde::{Deserialize, Serialize};
  5use std::{
  6    borrow::{Borrow, Cow},
  7    sync::Arc,
  8};
  9use util::arc_cow::ArcCow;
 10
 11/// A shared string is an immutable string that can be cheaply cloned in GPUI
 12/// tasks. Essentially an abstraction over an `Arc<str>` and `&'static str`,
 13#[derive(Deref, DerefMut, Eq, PartialEq, PartialOrd, Ord, Hash, Clone)]
 14pub struct SharedString(ArcCow<'static, str>);
 15
 16impl SharedString {
 17    /// Creates a static [`SharedString`] from a `&'static str`.
 18    pub const fn new_static(str: &'static str) -> Self {
 19        Self(ArcCow::Borrowed(str))
 20    }
 21
 22    /// Creates a [`SharedString`] from anything that can become an `Arc<str>`
 23    pub fn new(str: impl Into<Arc<str>>) -> Self {
 24        SharedString(ArcCow::Owned(str.into()))
 25    }
 26}
 27
 28impl JsonSchema for SharedString {
 29    fn inline_schema() -> bool {
 30        String::inline_schema()
 31    }
 32
 33    fn schema_name() -> Cow<'static, str> {
 34        String::schema_name()
 35    }
 36
 37    fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
 38        String::json_schema(generator)
 39    }
 40}
 41
 42impl Default for SharedString {
 43    fn default() -> Self {
 44        Self(ArcCow::Owned(Arc::default()))
 45    }
 46}
 47
 48impl AsRef<str> for SharedString {
 49    fn as_ref(&self) -> &str {
 50        &self.0
 51    }
 52}
 53
 54impl Borrow<str> for SharedString {
 55    fn borrow(&self) -> &str {
 56        self.as_ref()
 57    }
 58}
 59
 60impl std::fmt::Debug for SharedString {
 61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 62        self.0.fmt(f)
 63    }
 64}
 65
 66impl std::fmt::Display for SharedString {
 67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 68        write!(f, "{}", self.0.as_ref())
 69    }
 70}
 71
 72impl PartialEq<String> for SharedString {
 73    fn eq(&self, other: &String) -> bool {
 74        self.as_ref() == other
 75    }
 76}
 77
 78impl PartialEq<SharedString> for String {
 79    fn eq(&self, other: &SharedString) -> bool {
 80        self == other.as_ref()
 81    }
 82}
 83
 84impl PartialEq<str> for SharedString {
 85    fn eq(&self, other: &str) -> bool {
 86        self.as_ref() == other
 87    }
 88}
 89
 90impl<'a> PartialEq<&'a str> for SharedString {
 91    fn eq(&self, other: &&'a str) -> bool {
 92        self.as_ref() == *other
 93    }
 94}
 95
 96impl From<&SharedString> for SharedString {
 97    fn from(value: &SharedString) -> Self {
 98        value.clone()
 99    }
100}
101
102impl From<SharedString> for Arc<str> {
103    fn from(val: SharedString) -> Self {
104        match val.0 {
105            ArcCow::Borrowed(borrowed) => Arc::from(borrowed),
106            ArcCow::Owned(owned) => owned.clone(),
107        }
108    }
109}
110
111impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
112    fn from(value: T) -> Self {
113        Self(value.into())
114    }
115}
116
117impl From<SharedString> for String {
118    fn from(val: SharedString) -> Self {
119        val.0.to_string()
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        serializer.serialize_str(self.as_ref())
129    }
130}
131
132impl<'de> Deserialize<'de> for SharedString {
133    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
134    where
135        D: serde::Deserializer<'de>,
136    {
137        let s = String::deserialize(deserializer)?;
138        Ok(SharedString::from(s))
139    }
140}