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}