rune/runtime/
static_string.rs

1use 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/// Struct representing a static string.
16#[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    /// Construct a new static string.
55    #[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    /// Get the hash of the string.
66    #[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}