rust_i18n_support/
atomic_str.rs1use std::fmt;
2use std::ops::Deref;
3
4use arc_swap::{ArcSwapAny, Guard};
5use triomphe::Arc;
6
7pub struct AtomicStr(ArcSwapAny<Arc<String>>);
9
10struct GuardedStr(Guard<Arc<String>>);
12
13impl Deref for GuardedStr {
14 type Target = str;
15
16 fn deref(&self) -> &Self::Target {
17 self.0.as_str()
18 }
19}
20
21impl AtomicStr {
22 pub fn new(value: &str) -> Self {
24 let arced = Arc::new(value.into());
25 Self(ArcSwapAny::new(arced))
26 }
27
28 pub fn as_str(&self) -> impl Deref<Target = str> {
30 GuardedStr(self.0.load())
31 }
32
33 pub fn replace(&self, src: impl Into<String>) {
35 let arced = Arc::new(src.into());
36 self.0.store(arced);
37 }
38}
39
40impl From<&str> for AtomicStr {
41 fn from(value: &str) -> Self {
42 Self::new(value)
43 }
44}
45
46impl fmt::Display for AtomicStr {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.write_str(&self.as_str())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 fn test_str(s: &str) {
57 assert_eq!(s, "hello");
58 }
59
60 #[test]
61 fn test_atomic_str() {
62 let s = AtomicStr::from("hello");
63 test_str(&s.as_str());
64 }
65}