rtoolbox/
safe_string.rs
1use std::convert::Into;
2use std::ops::{Deref, DerefMut, Drop};
3use std::{ptr, sync::atomic};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct SafeString {
8 inner: String,
9}
10
11impl SafeString {
12 pub fn new() -> SafeString {
13 SafeString {
14 inner: String::new(),
15 }
16 }
17
18 pub fn from_string(inner: String) -> SafeString {
19 SafeString { inner }
20 }
21
22 pub fn into_inner(mut self) -> String {
23 std::mem::replace(&mut self.inner, String::new())
24 }
25}
26
27impl Drop for SafeString {
28 fn drop(&mut self) {
29 let default = u8::default();
30
31 for c in unsafe { self.inner.as_bytes_mut() } {
32 unsafe { ptr::write_volatile(c, default) };
33 }
34
35 atomic::fence(atomic::Ordering::SeqCst);
36 atomic::compiler_fence(atomic::Ordering::SeqCst);
37 }
38}
39
40impl Deref for SafeString {
41 type Target = String;
42
43 fn deref(&self) -> &String {
44 &self.inner
45 }
46}
47
48impl DerefMut for SafeString {
49 fn deref_mut(&mut self) -> &mut Self::Target {
50 &mut self.inner
51 }
52}
53
54impl Into<SafeString> for String {
55 fn into(self) -> SafeString {
56 SafeString::from_string(self)
57 }
58}
59
60impl<'a> Into<SafeString> for &'a str {
61 fn into(self) -> SafeString {
62 self.to_string().into()
63 }
64}