yash_semantics/expansion/initial/
slice.rs1use super::super::Error;
20use super::Env;
21use super::Expand;
22use super::Phrase;
23
24impl<T: Expand> Expand for [T] {
33 async fn expand(&self, env: &mut Env<'_>) -> Result<Phrase, Error> {
34 if self.is_empty() {
35 return Ok(Phrase::one_empty_field());
36 }
37
38 let mut phrase = Phrase::zero_fields();
39 for item in self {
40 phrase += item.expand(env).await?;
41 }
42 Ok(phrase)
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::expansion::Error;
50 use crate::expansion::attr::AttrChar;
51 use crate::expansion::attr::Origin;
52 use futures_util::FutureExt as _;
53 use std::cell::Cell;
54
55 fn dummy_attr_char(value: char) -> AttrChar {
56 AttrChar {
57 value,
58 origin: Origin::Literal,
59 is_quoted: false,
60 is_quoting: false,
61 }
62 }
63
64 struct Stub(Cell<Option<Result<Phrase, Error>>>);
65
66 impl Stub {
67 fn new(result: Result<Phrase, Error>) -> Self {
68 Stub(Cell::new(Some(result)))
69 }
70 }
71
72 impl Expand for Stub {
73 async fn expand(&self, _: &mut Env<'_>) -> Result<Phrase, Error> {
74 self.0.take().expect("expand should be called only once")
75 }
76 }
77
78 #[test]
79 fn empty_slice() {
80 let mut env = yash_env::Env::new_virtual();
81 let mut env = Env::new(&mut env);
82 let stubs: [Stub; 0] = [];
83 let result = stubs.expand(&mut env).now_or_never().unwrap();
84 assert_eq!(result, Ok(Phrase::one_empty_field()));
85 }
86
87 #[test]
88 fn slice_of_one_item_returning_zero_fields() {
89 let mut env = yash_env::Env::new_virtual();
90 let mut env = Env::new(&mut env);
91 let stubs = [Stub::new(Ok(Phrase::zero_fields()))];
92 let result = stubs.expand(&mut env).now_or_never().unwrap();
93 assert_eq!(result, Ok(Phrase::zero_fields()));
94 }
95
96 #[test]
97 fn slice_of_many_items_returning_zero_fields() {
98 let mut env = yash_env::Env::new_virtual();
99 let mut env = Env::new(&mut env);
100 let stubs = [
101 Stub::new(Ok(Phrase::zero_fields())),
102 Stub::new(Ok(Phrase::zero_fields())),
103 Stub::new(Ok(Phrase::zero_fields())),
104 ];
105 let result = stubs.expand(&mut env).now_or_never().unwrap();
106 assert_eq!(result, Ok(Phrase::zero_fields()));
107 }
108
109 #[test]
110 fn slice_of_many_items_each_returning_one_empty_field() {
111 let mut env = yash_env::Env::new_virtual();
112 let mut env = Env::new(&mut env);
113 let stubs = [
114 Stub::new(Ok(Phrase::one_empty_field())),
115 Stub::new(Ok(Phrase::one_empty_field())),
116 Stub::new(Ok(Phrase::one_empty_field())),
117 ];
118 let result = stubs.expand(&mut env).now_or_never().unwrap();
119 assert_eq!(result, Ok(Phrase::one_empty_field()));
120 }
121
122 #[test]
123 fn slice_of_many_items_each_returning_one_non_empty_field() {
124 let mut env = yash_env::Env::new_virtual();
125 let mut env = Env::new(&mut env);
126 let a = dummy_attr_char('a');
127 let b = dummy_attr_char('b');
128 let c = dummy_attr_char('c');
129 let stubs = [
130 Stub::new(Ok(Phrase::Char(a))),
131 Stub::new(Ok(Phrase::Char(b))),
132 Stub::new(Ok(Phrase::Char(c))),
133 ];
134 let result = stubs.expand(&mut env).now_or_never().unwrap();
135 assert_eq!(result, Ok(Phrase::Field(vec![a, b, c])));
136 }
137}