string_literals/lib.rs
1/*!
2A very tiny crate with Rust macros to more easily create String types.
3
4When creating string literals in Rust, the given type is `&str`. To create an owned `String` type,
5you either need to:
6
7- pass in the literal to `String::from()`,
8- call `.to_owned()`, or `.to_string()` on the `&str` literal
9
10### Strings
11
12```rust
13use string_literals::s;
14
15let old = "Hello, world!".to_owned();
16let new = s!("Hello, world!");
17```
18
19### Arrays, vectors
20
21```rust
22use string_literals::{string_arr, string_vec};
23
24let old_arr: [String; 3] = ["Banana".to_owned(), "Apple".to_owned(), "Orange".to_owned()];
25let new_arr: [String; 3] = string_arr!["Banana", "Apple", "Orange"];
26
27let old_vec = vec!["Banana".to_owned(), "Apple".to_owned(), "Orange".to_owned()];
28let new_vec = string_vec!["Banana", "Apple", "Orange"];
29```
30
31### Hash maps
32
33```rust
34use std::collections::HashMap;
35use string_literals::string_hashmap;
36
37let mut old1: HashMap<String, String> = HashMap::new();
38old1.insert("Banana".to_owned(), "Good".to_owned());
39old1.insert("Apple".to_owned(), "Okay".to_owned());
40
41let old2: HashMap<String, String> = HashMap::from([
42 ("Banana".to_owned(), "Good".to_owned()),
43 ("Apple".to_owned(), "Okay".to_owned()),
44]);
45
46let new: HashMap<String, String> = string_hashmap! {
47 "Banana" => "Good",
48 "Apple" => "Okay",
49};
50```
51*/
52
53/// Create a [`String`] literal
54///
55/// This provides a slightly shorter alternative to creating a `String`
56/// from a literal.
57///
58/// # Examples
59/// Empty strings:
60/// ```
61/// use string_literals::s;
62///
63/// let old = String::new();
64/// let s1 = s!();
65/// let s2 = s!("");
66/// assert!(s1.is_empty());
67/// assert!(s2.is_empty());
68/// ```
69///
70/// Non-empty strings:
71/// ```
72/// use string_literals::s;
73///
74/// let old1 = String::from("Alice");
75/// let old2 = "Alice".to_owned();
76/// let old3 = "Alice".to_string();
77/// let new = s!("Alice");
78/// assert_eq!(new, String::from("Alice"));
79/// ```
80#[macro_export]
81macro_rules! s {
82 () => {
83 String::new()
84 };
85 ("") => {
86 String::new()
87 };
88 ($s: expr) => {
89 $s.to_owned()
90 };
91}
92
93/// Create an [`array`] of `[String; N]` with string literals
94///
95/// # Examples
96/// Empty arrays:
97/// ```
98/// use string_literals::string_arr;
99///
100/// let arr: [String; 0] = string_arr![];
101/// assert!(arr.is_empty());
102/// ```
103///
104/// Non-empty arrays:
105/// ```
106/// use string_literals::string_arr;
107///
108/// let old: [String; 2] = [String::from("Alice"), String::from("Bob")];
109/// let new: [String; 2] = string_arr!["Alice", "Bob"];
110/// assert_eq!(new.len(), 2);
111/// assert_eq!(new[0], String::from("Alice"));
112/// assert_eq!(new[1], String::from("Bob"));
113/// ```
114#[macro_export]
115macro_rules! string_arr {
116 () => {
117 []
118 };
119 ($($x:expr),+ $(,)?) => {
120 [$($x.to_owned()),*]
121 }
122}
123
124/// Create a [`Vec`] of `Vec<String>` with string literals.
125///
126/// This macro also allows zero arguments. In this case however, it would be
127/// shorter to call `vec![]` or `Vec::new()`.
128///
129/// # Examples
130/// ```
131/// use string_literals::string_vec;
132///
133/// let old: Vec<String> = vec![String::from("Alice"), String::from("Bob")];
134/// let new: Vec<String> = string_vec!["Alice", "Bob"];
135/// assert_eq!(new.len(), 2);
136/// assert_eq!(new[0], "Alice".to_owned());
137/// assert_eq!(new[1], "Bob".to_owned());
138/// ```
139#[macro_export]
140macro_rules! string_vec {
141 () => {
142 Vec::new()
143 };
144 ($($x:expr),+ $(,)?) => {
145 vec![$($x.to_owned()),+]
146 };
147}
148
149/// Create a [`HashMap`](std::collections::HashMap) of `HashMap<String, String>` with string literals
150///
151/// This macro also allows zero arguments (an empty hash map). In this case
152/// however, it would be shorter in length to call `HashMap::new()`.
153///
154/// # Examples
155/// Empty hash maps:
156/// ```
157/// use std::collections::HashMap;
158/// use string_literals::string_hashmap;
159///
160/// let map: HashMap<String, String> = string_hashmap!{};
161/// assert!(map.is_empty());
162/// ```
163///
164/// Non-empty hash maps:
165/// ```
166/// use std::collections::HashMap;
167/// use string_literals::string_hashmap;
168///
169/// let map: HashMap<String, String> = string_hashmap!{
170/// "Banana" => "Good",
171/// "Apple" => "Okay",
172/// };
173/// assert_eq!(map[&"Banana".to_owned()], "Good".to_owned());
174/// assert_eq!(map[&"Apple".to_owned()], "Okay".to_owned());
175/// ```
176#[macro_export]
177macro_rules! string_hashmap {
178 () => {
179 ::std::collections::HashMap::new()
180 };
181 ($($k:expr => $v:expr),+ $(,)?) => {
182 ::std::collections::HashMap::from([
183 $(($k.to_owned(), $v.to_owned())),+
184 ])
185 };
186}