rune/runtime/
static_string.rs1use core::cmp;
2use core::fmt;
3use core::hash;
4use core::ops;
5
6#[cfg(feature = "musli")]
7use musli::{Decode, Encode};
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11use crate::alloc::prelude::*;
12use crate::alloc::{self, String};
13use crate::hash::{Hash, IntoHash};
14
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17#[cfg_attr(feature = "musli", derive(Encode, Decode))]
18pub struct StaticString {
19 inner: String,
20 hash: Hash,
21}
22
23impl cmp::PartialEq for StaticString {
24 #[inline]
25 fn eq(&self, other: &Self) -> bool {
26 self.hash == other.hash && self.inner == other.inner
27 }
28}
29
30impl cmp::Eq for StaticString {}
31
32impl cmp::PartialOrd for StaticString {
33 #[inline]
34 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
35 Some(self.cmp(other))
36 }
37}
38
39impl cmp::Ord for StaticString {
40 #[inline]
41 fn cmp(&self, other: &Self) -> cmp::Ordering {
42 self.inner.cmp(&other.inner)
43 }
44}
45
46impl hash::Hash for StaticString {
47 #[inline]
48 fn hash<H: hash::Hasher>(&self, state: &mut H) {
49 self.hash.hash(state)
50 }
51}
52
53impl StaticString {
54 #[inline]
56 pub fn new<S>(s: S) -> alloc::Result<Self>
57 where
58 S: AsRef<str>,
59 {
60 let inner = s.as_ref().try_to_owned()?;
61 let hash = s.as_ref().into_hash();
62 Ok(Self { inner, hash })
63 }
64
65 #[inline]
67 pub fn hash(&self) -> Hash {
68 self.hash
69 }
70}
71
72impl AsRef<String> for StaticString {
73 #[inline]
74 fn as_ref(&self) -> &String {
75 &self.inner
76 }
77}
78
79impl fmt::Display for StaticString {
80 #[inline]
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 self.inner.fmt(f)
83 }
84}
85
86impl fmt::Debug for StaticString {
87 #[inline]
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 write!(f, "{:?}", &self.inner)
90 }
91}
92
93impl ops::Deref for StaticString {
94 type Target = String;
95
96 #[inline]
97 fn deref(&self) -> &Self::Target {
98 &self.inner
99 }
100}
101
102impl From<String> for StaticString {
103 #[inline]
104 fn from(inner: String) -> Self {
105 let hash = inner.as_str().into_hash();
106 Self { inner, hash }
107 }
108}