rune/runtime/
static_string.rs

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