Skip to content

Commit 20a6e6b

Browse files
committed
ADD: header_vec! macro sumilar to the stdlib vec!() macro
1 parent 243fd4b commit 20a6e6b

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

src/lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,3 +1129,68 @@ impl<'a, H, T: Copy + 'a> Extend<&'a T> for HeaderVec<H, T> {
11291129
iter.for_each(|item| self.push(*item));
11301130
}
11311131
}
1132+
1133+
/// Creates a HeaderVec with an optional header and elements. Similar to what the stdlib
1134+
/// `vec!()` macro does for `Vec`. When no header is provided, the unit `()` is used.
1135+
/// Note that the syntax differs slightly from the `vec!()` macro. When a header is provided, it
1136+
/// must be followed by a semicolon before the elements are in a square bracket list. This is to
1137+
/// distinguish between the header and the elements.
1138+
///
1139+
/// # Examples
1140+
///
1141+
/// ```
1142+
/// # use header_vec::header_vec;
1143+
/// // Create a HeaderVec with default header `()`
1144+
/// let v = header_vec![1, 2, 3];
1145+
/// assert_eq!(*v, ());
1146+
/// assert_eq!(v.as_slice(), &[1, 2, 3]);
1147+
///
1148+
/// // Create a HeaderVec with a custom header
1149+
/// let v = header_vec!("header"; [1, 2, 3]);
1150+
/// assert_eq!(*v, "header");
1151+
/// assert_eq!(v.as_slice(), &[1, 2, 3]);
1152+
///
1153+
/// // Create a HeaderVec with repetition (default header `()`)
1154+
/// let v = header_vec![42; 5];
1155+
/// assert_eq!(*v, ());
1156+
/// assert_eq!(v.as_slice(), &[42, 42, 42, 42, 42]);
1157+
///
1158+
/// // Create a HeaderVec with custom header and repetition
1159+
/// let v = header_vec!("header"; [42; 5]);
1160+
/// assert_eq!(*v, "header");
1161+
/// assert_eq!(v.as_slice(), &[42, 42, 42, 42, 42]);
1162+
/// ```
1163+
#[macro_export]
1164+
macro_rules! header_vec {
1165+
() => {
1166+
$crate::HeaderVec::new(())
1167+
};
1168+
1169+
($header:expr; []) => {
1170+
$crate::HeaderVec::new($header)
1171+
};
1172+
1173+
($header:expr; [$($elem:expr),+ $(,)?]) => {{
1174+
let mut vec = $crate::HeaderVec::new($header);
1175+
vec.extend(IntoIterator::into_iter([$($elem),+]));
1176+
vec
1177+
}};
1178+
1179+
($header:expr; [$elem:expr; $n:expr]) => {{
1180+
let mut vec = $crate::HeaderVec::new($header);
1181+
vec.extend(std::iter::repeat($elem).take($n));
1182+
vec
1183+
}};
1184+
1185+
($elem:expr; $n:expr) => {{
1186+
let mut vec = $crate::HeaderVec::new(());
1187+
vec.extend(std::iter::repeat($elem).take($n));
1188+
vec
1189+
}};
1190+
1191+
($($elem:expr),+ $(,)?) => {{
1192+
let mut vec = $crate::HeaderVec::new(());
1193+
vec.extend(IntoIterator::into_iter([$($elem),+]));
1194+
vec
1195+
}};
1196+
}

tests/std.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,97 @@ xmacro! {
6363
assert_eq!(hv.as_slice(), $result);
6464
}
6565
}
66+
67+
// testing the header_vec!() macro
68+
#[test]
69+
fn test_empty_with_default_header() {
70+
let v: HeaderVec<(), i32> = header_vec![];
71+
assert_eq!(*v, ());
72+
assert!(v.is_empty());
73+
}
74+
75+
#[test]
76+
fn test_empty_with_custom_header() {
77+
let v: HeaderVec<&str, i32> = header_vec!("header"; []);
78+
assert_eq!(*v, "header");
79+
assert!(v.is_empty());
80+
}
81+
82+
#[test]
83+
fn test_values_with_custom_header() {
84+
let v = header_vec!("header"; [1, 2, 3]);
85+
assert_eq!(*v, "header");
86+
assert_eq!(v.as_slice(), &[1, 2, 3]);
87+
assert_eq!(v.len(), 3);
88+
89+
let v = header_vec!("header"; [1, 2, 3,]);
90+
assert_eq!(*v, "header");
91+
assert_eq!(v.as_slice(), &[1, 2, 3]);
92+
}
93+
94+
#[test]
95+
fn test_repetition_with_custom_header() {
96+
let v = header_vec!("header"; [42; 5]);
97+
assert_eq!(*v, "header");
98+
assert_eq!(v.as_slice(), &[42, 42, 42, 42, 42]);
99+
assert_eq!(v.len(), 5);
100+
}
101+
102+
#[test]
103+
fn test_repetition_with_default_header() {
104+
let v = header_vec![42; 5];
105+
assert_eq!(*v, ());
106+
assert_eq!(v.as_slice(), &[42, 42, 42, 42, 42]);
107+
assert_eq!(v.len(), 5);
108+
}
109+
110+
#[test]
111+
fn test_values_with_default_header() {
112+
let v = header_vec![1, 2, 3];
113+
assert_eq!(*v, ());
114+
assert_eq!(v.as_slice(), &[1, 2, 3]);
115+
assert_eq!(v.len(), 3);
116+
117+
let v = header_vec![1, 2, 3,];
118+
assert_eq!(*v, ());
119+
assert_eq!(v.as_slice(), &[1, 2, 3]);
120+
}
121+
122+
#[test]
123+
fn test_non_copy_types() {
124+
let v = header_vec!("header"; [String::from("hello"), String::from("world")]);
125+
assert_eq!(*v, "header");
126+
assert_eq!(
127+
v.as_slice(),
128+
&[String::from("hello"), String::from("world")]
129+
);
130+
131+
let v = header_vec![String::from("repeated"); 2];
132+
assert_eq!(*v, ());
133+
assert_eq!(
134+
v.as_slice(),
135+
&[String::from("repeated"), String::from("repeated")]
136+
);
137+
}
138+
139+
#[test]
140+
fn test_zero_repetitions() {
141+
let v: HeaderVec<(), i32> = header_vec![42; 0];
142+
assert_eq!(*v, ());
143+
assert!(v.is_empty());
144+
145+
let v: HeaderVec<&str, i32> = header_vec!("header"; [42; 0]);
146+
assert_eq!(*v, "header");
147+
assert!(v.is_empty());
148+
}
149+
150+
#[test]
151+
fn test_single_element() {
152+
let v = header_vec![42];
153+
assert_eq!(*v, ());
154+
assert_eq!(v.as_slice(), &[42]);
155+
156+
let v = header_vec!("header"; [42]);
157+
assert_eq!(*v, "header");
158+
assert_eq!(v.as_slice(), &[42]);
159+
}

0 commit comments

Comments
 (0)