vec_string_to_static_str/
lib.rs

1//! src/lib.rs
2
3/// Converts a vector of `String`s into a vector of `&'static str`.
4///
5/// This function leaks memory as it uses `Box::leak` to create
6/// static string slices from the input strings. Use with caution.
7///
8/// # Arguments
9///
10/// * `strings` - A vector of `String`s to be converted.
11///
12/// # Returns
13///
14/// A vector of `&'static str` references to the input strings.
15///
16/// # Example
17///
18/// ```
19/// use vec_string_to_static_str::vec_string_to_static_str;
20///
21/// let strings = vec![String::from("hello"), String::from("world")];
22/// let static_strs = vec_string_to_static_str(&strings);
23/// assert_eq!(static_strs, vec!["hello", "world"]);
24/// ```
25pub fn vec_string_to_static_str(strings: &Vec<String>) -> Vec<&'static str> {
26    let mut strs: Vec<&'static str> = Vec::new();
27
28    for string in strings {
29        strs.push(Box::leak(string.clone().into_boxed_str()));
30    }
31
32    strs
33}
34
35#[cfg(feature = "unsafe")]
36/// Unsafely converts a vector of `String`s into a vector of `&'static str`.
37///
38/// This function uses `std::mem::transmute` to convert string slices
39/// into static string slices without leaking memory. Use this function
40/// only when you are certain of the lifetime safety.
41///
42/// # Arguments
43///
44/// * `strings` - A vector of `String`s to be converted.
45///
46/// # Returns
47///
48/// A vector of `&'static str` references to the input strings.
49///
50/// # Safety
51///
52/// This function is unsafe because it extends the lifetime of the string
53/// slices to `'static`, which can cause undefined behavior if not used correctly.
54///
55/// # Example
56///
57/// ```
58/// use vec_string_to_static_str::unsafe_vec_string_to_static_str;
59///
60/// let strings = vec![String::from("hello"), String::from("world")];
61/// let static_strs = unsafe_vec_string_to_static_str(&strings);
62/// assert_eq!(static_strs, vec!["hello", "world"]);
63/// ```
64pub fn unsafe_vec_string_to_static_str(strings: &Vec<String>) -> Vec<&'static str> {
65    let mut strs: Vec<&'static str> = Vec::new();
66
67    for string in strings {
68        strs.push(unsafe { std::mem::transmute::<&str, &'static str>(string.as_str()) });
69    }
70
71    strs
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn vec_string_to_static_str_from_literals() {
80        let strings = vec!["string_a".to_string(), "string_b".to_string()];
81
82        let actual = vec_string_to_static_str(&strings);
83
84        assert_eq!(vec!["string_a", "string_b"], actual);
85    }
86
87    #[test]
88    fn vec_string_to_static_str_from_dynamic_allocation() {
89        let strings = vec![String::from("string_a"), String::from("string_b")];
90
91        let actual = vec_string_to_static_str(&strings);
92
93        assert_eq!(vec!["string_a", "string_b"], actual);
94    }
95    #[test]
96    fn vec_string_to_static_str_empty_vector() {
97        let strings: Vec<String> = Vec::new();
98
99        let actual = vec_string_to_static_str(&strings);
100
101        assert_eq!(Vec::<&'static str>::new(), actual);
102    }
103
104    #[test]
105    fn vec_string_to_static_str_mixed_content() {
106        let strings = vec!["".to_string(), "a".to_string(), "longer string".to_string()];
107
108        let actual = vec_string_to_static_str(&strings);
109
110        assert_eq!(vec!["", "a", "longer string"], actual);
111    }
112
113    #[test]
114    fn vec_string_to_static_str_special_characters() {
115        let strings = vec![
116            "hello, world!".to_string(),
117            "你好,世界!".to_string(),
118            "こんにちは、世界!".to_string(),
119            "안녕하세요, 세계!".to_string(),
120        ];
121
122        let actual = vec_string_to_static_str(&strings);
123
124        assert_eq!(
125            vec![
126                "hello, world!",
127                "你好,世界!",
128                "こんにちは、世界!",
129                "안녕하세요, 세계!"
130            ],
131            actual
132        );
133    }
134
135    #[test]
136    #[cfg(feature = "unsafe")]
137    fn unsafe_vec_string_to_static_str_from_literals() {
138        let strings = vec!["string_a".to_string(), "string_b".to_string()];
139
140        let actual = unsafe_vec_string_to_static_str(&strings);
141
142        assert_eq!(vec!["string_a", "string_b"], actual);
143    }
144
145    #[test]
146    #[cfg(feature = "unsafe")]
147    fn unsafe_vec_string_to_static_str_from_dynamic_allocation() {
148        let strings = vec![String::from("string_a"), String::from("string_b")];
149
150        let actual = unsafe_vec_string_to_static_str(&strings);
151
152        assert_eq!(vec!["string_a", "string_b"], actual);
153    }
154
155    #[test]
156    #[cfg(feature = "unsafe")]
157    fn unsafe_vec_string_to_static_str_empty_vector() {
158        let strings: Vec<String> = Vec::new();
159
160        let actual = unsafe_vec_string_to_static_str(&strings);
161
162        assert_eq!(Vec::<&'static str>::new(), actual);
163    }
164
165    #[test]
166    #[cfg(feature = "unsafe")]
167    fn unsafe_vec_string_to_static_str_mixed_content() {
168        let strings = vec!["".to_string(), "a".to_string(), "longer string".to_string()];
169
170        let actual = unsafe_vec_string_to_static_str(&strings);
171
172        assert_eq!(vec!["", "a", "longer string"], actual);
173    }
174
175    #[test]
176    #[cfg(feature = "unsafe")]
177    fn unsafe_vec_string_to_static_str_special_characters() {
178        let strings = vec![
179            "hello, world!".to_string(),
180            "你好,世界!".to_string(),
181            "こんにちは、世界!".to_string(),
182            "안녕하세요, 세계!".to_string(),
183        ];
184
185        let actual = unsafe_vec_string_to_static_str(&strings);
186
187        assert_eq!(
188            vec![
189                "hello, world!",
190                "你好,世界!",
191                "こんにちは、世界!",
192                "안녕하세요, 세계!"
193            ],
194            actual
195        );
196    }
197}