cloneable_errors/
strings.rs

1/* 
2* This file is part of the cloneable_errors library, licensed under the MIT license: 
3* https://github.com/mini-bomba/cloneable_errors
4*
5* Copyright (C) 2024 mini_bomba
6*/
7
8use std::{fmt::Display, ptr, sync::Arc};
9
10#[cfg(feature = "serde")]
11use serde::{Serialize, Deserialize};
12
13
14/// A helper enum for easily cloneable strings
15///
16/// NOTE: `SharedString`s are compared using pointer equality
17#[derive(Debug, Clone)]
18pub enum SharedString {
19    Arc(Arc<str>),
20    Static(&'static str),
21}
22
23/// `SharedStrings` are compared using pointer equality.
24impl PartialEq for SharedString {
25    fn eq(&self, other: &Self) -> bool {
26        // Compare by pointer
27        match (self, other) {
28            (Self::Arc(this), Self::Arc(other)) => Arc::ptr_eq(this, other),
29            (Self::Static(this), Self::Static(other)) => ptr::eq(this, other),
30            // different types
31            _ => false
32        }
33    }
34}
35impl Eq for SharedString {}
36
37impl Display for SharedString {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        match self {
40            SharedString::Arc(s) => write!(f, "{s}"),
41            SharedString::Static(s) => write!(f, "{s}"),
42        }
43    }
44}
45
46impl From<&'static str> for SharedString {
47    fn from(value: &'static str) -> Self {
48        SharedString::Static(value)
49    }
50}
51
52impl From<Arc<str>> for SharedString {
53    fn from(value: Arc<str>) -> Self {
54        SharedString::Arc(value)
55    }
56}
57
58impl From<String> for SharedString
59{
60    fn from(value: String) -> Self {
61        SharedString::Arc(Arc::from(value))
62    }
63}
64
65// serde
66
67#[cfg(feature = "serde")]
68#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
69impl Serialize for SharedString {
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where S: serde::Serializer
72    {
73        match self {
74            SharedString::Arc(s) => serializer.serialize_str(s),
75            SharedString::Static(s) => serializer.serialize_str(s),
76        }
77    }
78}
79
80#[cfg(feature = "serde")]
81#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
82impl<'de> Deserialize<'de> for SharedString {
83    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
84    where D: serde::Deserializer<'de>
85    {
86        Ok(Self::Arc(Arc::<str>::deserialize(deserializer)?))
87    }
88}