libreda_db/
rc_string.rs

1// Copyright (c) 2020-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! `RcString` is a simple data structure for the representation of strings.
7//! In contrast to `String`, `RcString` can be efficiently cloned. It is intended
8//! to be used in cases where objects are indexed by a human readable name.
9//!
10//! # Example
11//!
12//! ```
13//! use libreda_db::rc_string::RcString;
14//!
15//! let a: String = "A".to_string();
16//!
17//! let a1_rc = RcString::from(a);
18//! let a2_rc = RcString::from("A");
19//!
20//! // No string data is copied here.
21//! let a3_rc = a1_rc.clone();
22//!
23//! assert_eq!(a1_rc, a2_rc);
24//! assert_eq!(a1_rc, a3_rc);
25//!
26//! ```
27
28use iron_shapes::point::Deref;
29use std::borrow::Borrow;
30use std::hash::{Hash, Hasher};
31use std::sync::Arc;
32
33/// Resource counted string, used for names.
34/// `RcString`s can be efficiently cloned.
35#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37pub struct RcString {
38    string: Arc<String>,
39}
40
41impl std::fmt::Display for RcString {
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        std::fmt::Display::fmt(self.string.as_str(), f)
44    }
45}
46
47impl RcString {
48    /// Create a new resource counted string.
49    pub fn new(string: String) -> Self {
50        RcString {
51            string: Arc::new(string),
52        }
53    }
54}
55
56impl Hash for RcString {
57    fn hash<H: Hasher>(&self, state: &mut H) {
58        self.string.hash(state)
59    }
60}
61
62impl Deref for RcString {
63    type Target = String;
64
65    fn deref(&self) -> &Self::Target {
66        self.string.deref()
67    }
68}
69
70impl Borrow<str> for RcString {
71    fn borrow(&self) -> &str {
72        self.as_str()
73    }
74}
75
76impl Borrow<String> for RcString {
77    fn borrow(&self) -> &String {
78        self.string.deref()
79    }
80}
81
82impl From<String> for RcString {
83    fn from(string: String) -> Self {
84        Self::new(string)
85    }
86}
87
88impl From<Arc<String>> for RcString {
89    fn from(string: Arc<String>) -> Self {
90        Self { string }
91    }
92}
93
94impl From<&Arc<String>> for RcString {
95    fn from(string: &Arc<String>) -> Self {
96        Self {
97            string: string.clone(),
98        }
99    }
100}
101
102impl From<&str> for RcString {
103    fn from(s: &str) -> Self {
104        Self::new(s.to_string())
105    }
106}
107
108impl From<RcString> for String {
109    fn from(val: RcString) -> Self {
110        val.string.to_string()
111    }
112}