sample_config/
implementations.rs

1//! Implementations of the [SampleConfig] trait for types.
2
3use std::{
4	borrow::Cow,
5	net::SocketAddr,
6	path::{Path, PathBuf},
7};
8
9use crate::{OutputType, SampleConfig};
10
11/// Generate implementations for [`SampleConfig`] for types that need `""`
12/// around their value and implement `Display`.
13macro_rules! impl_sample_config_stringified {
14	($($string: ty),*$(,)?) => {
15		$(
16			impl SampleConfig for $string {
17				const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Value;
18
19				#[cfg(feature = "yaml")]
20				fn generate_sample_yaml(&self) -> String {
21					format!("\"{}\"", self)
22				}
23
24				#[cfg(feature = "json")]
25				fn generate_sample_json(&self) -> String {
26					format!("\"{}\"", self)
27				}
28			}
29		)*
30	};
31}
32
33impl_sample_config_stringified!(String, str, SocketAddr);
34#[cfg(feature = "url")]
35impl_sample_config_stringified!(url::Url);
36#[cfg(feature = "tracing")]
37impl_sample_config_stringified!(tracing::Level, tracing::level_filters::LevelFilter);
38
39/// Generate implementations for [`SampleConfig`] for types that just use
40/// `to_string` to generate valid output.
41macro_rules! impl_sample_config_raw {
42	($($number: ty),*$(,)?) => {
43		$(
44			impl SampleConfig for $number {
45				const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Value;
46
47				#[cfg(feature = "yaml")]
48				fn generate_sample_yaml(&self) -> String {
49					self.to_string()
50				}
51
52				#[cfg(feature = "json")]
53				fn generate_sample_json(&self) -> String {
54					self.to_string()
55				}
56			}
57		)*
58	};
59}
60
61impl_sample_config_raw!(
62	bool, usize, isize, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64
63);
64
65impl<T: SampleConfig> SampleConfig for &T {
66	const SAMPLE_OUTPUT_TYPE: OutputType = T::SAMPLE_OUTPUT_TYPE;
67
68	#[cfg(feature = "yaml")]
69	fn generate_sample_yaml(&self) -> String {
70		<T as SampleConfig>::generate_sample_yaml(self)
71	}
72
73	#[cfg(feature = "json")]
74	fn generate_sample_json(&self) -> String {
75		<T as SampleConfig>::generate_sample_json(self)
76	}
77}
78
79impl<T: SampleConfig> SampleConfig for &mut T {
80	const SAMPLE_OUTPUT_TYPE: OutputType = T::SAMPLE_OUTPUT_TYPE;
81
82	#[cfg(feature = "yaml")]
83	fn generate_sample_yaml(&self) -> String {
84		<T as SampleConfig>::generate_sample_yaml(self)
85	}
86
87	#[cfg(feature = "json")]
88	fn generate_sample_json(&self) -> String {
89		<T as SampleConfig>::generate_sample_json(self)
90	}
91}
92
93impl<T: SampleConfig> SampleConfig for Box<T> {
94	const SAMPLE_OUTPUT_TYPE: OutputType = T::SAMPLE_OUTPUT_TYPE;
95
96	#[cfg(feature = "yaml")]
97	fn generate_sample_yaml(&self) -> String {
98		<T as SampleConfig>::generate_sample_yaml(self)
99	}
100
101	#[cfg(feature = "json")]
102	fn generate_sample_json(&self) -> String {
103		<T as SampleConfig>::generate_sample_json(self)
104	}
105}
106
107impl<'a, T: SampleConfig + ToOwned> SampleConfig for Cow<'a, T> {
108	const SAMPLE_OUTPUT_TYPE: OutputType = T::SAMPLE_OUTPUT_TYPE;
109
110	#[cfg(feature = "yaml")]
111	fn generate_sample_yaml(&self) -> String {
112		<T as SampleConfig>::generate_sample_yaml(self)
113	}
114
115	#[cfg(feature = "json")]
116	fn generate_sample_json(&self) -> String {
117		<T as SampleConfig>::generate_sample_json(self)
118	}
119}
120
121impl<T: SampleConfig> SampleConfig for Option<T> {
122	const SAMPLE_OUTPUT_TYPE: OutputType = T::SAMPLE_OUTPUT_TYPE;
123
124	#[cfg(feature = "yaml")]
125	fn generate_sample_yaml(&self) -> String {
126		match self {
127			None => "null".to_owned(),
128			Some(value) => value.generate_sample_yaml(),
129		}
130	}
131
132	#[cfg(feature = "json")]
133	fn generate_sample_json(&self) -> String {
134		match self {
135			None => "null".to_owned(),
136			Some(value) => value.generate_sample_json(),
137		}
138	}
139}
140
141impl<T: SampleConfig> SampleConfig for Vec<T> {
142	const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Fields;
143
144	#[cfg(feature = "yaml")]
145	fn generate_sample_yaml(&self) -> String {
146		if self.is_empty() {
147			return "[]".to_owned();
148		}
149
150		let mut sample = String::new();
151		for value in self {
152			sample.push_str("- ");
153			if T::SAMPLE_OUTPUT_TYPE == OutputType::Value {
154				sample.push_str(&value.generate_sample_yaml());
155			} else {
156				sample.push_str("\n  ");
157				let sub_sample = value.generate_sample_yaml().replace('\n', "\n  ");
158				sample.push_str(sub_sample.trim());
159			}
160			sample.push('\n');
161		}
162		sample
163	}
164
165	#[cfg(feature = "json")]
166	fn generate_sample_json(&self) -> String {
167		if self.is_empty() {
168			return "[]".to_owned();
169		}
170
171		let mut sample = String::new();
172		sample.push_str("[\n");
173		for value in self {
174			sample.push_str("  ");
175			if T::SAMPLE_OUTPUT_TYPE == OutputType::Value {
176				sample.push_str(&value.generate_sample_json());
177			} else {
178				let sub_sample = value.generate_sample_json().replace('\n', "\n  ");
179				sample.push_str(sub_sample.trim());
180			}
181			sample.push_str(",\n");
182		}
183		sample.pop();
184		sample.pop();
185		sample.push_str("\n]\n");
186		sample
187	}
188}
189
190impl<T: SampleConfig> SampleConfig for [T] {
191	const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Fields;
192
193	#[cfg(feature = "yaml")]
194	fn generate_sample_yaml(&self) -> String {
195		if self.is_empty() {
196			return "[]".to_owned();
197		}
198
199		let mut sample = String::new();
200		for value in self {
201			sample.push_str("- ");
202			if T::SAMPLE_OUTPUT_TYPE == OutputType::Value {
203				sample.push_str(&value.generate_sample_yaml());
204			} else {
205				sample.push_str("\n  ");
206				let sub_sample = value.generate_sample_yaml().replace('\n', "\n  ");
207				sample.push_str(sub_sample.trim());
208			}
209			sample.push('\n');
210		}
211		sample
212	}
213
214	#[cfg(feature = "json")]
215	fn generate_sample_json(&self) -> String {
216		if self.is_empty() {
217			return "[]".to_owned();
218		}
219
220		let mut sample = String::new();
221		sample.push_str("[\n");
222		for value in self {
223			sample.push_str("  ");
224			if T::SAMPLE_OUTPUT_TYPE == OutputType::Value {
225				sample.push_str(&value.generate_sample_json());
226			} else {
227				let sub_sample = value.generate_sample_json().replace('\n', "\n  ");
228				sample.push_str(sub_sample.trim());
229			}
230			sample.push_str(",\n");
231		}
232		sample.pop();
233		sample.pop();
234		sample.push_str("\n]\n");
235		sample
236	}
237}
238
239impl SampleConfig for PathBuf {
240	const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Value;
241
242	#[cfg(feature = "yaml")]
243	fn generate_sample_yaml(&self) -> String {
244		format!("\"{}\"", self.display())
245	}
246
247	#[cfg(feature = "json")]
248	fn generate_sample_json(&self) -> String {
249		format!("\"{}\"", self.display())
250	}
251}
252
253impl SampleConfig for Path {
254	const SAMPLE_OUTPUT_TYPE: OutputType = OutputType::Value;
255
256	#[cfg(feature = "yaml")]
257	fn generate_sample_yaml(&self) -> String {
258		format!("\"{}\"", self.display())
259	}
260
261	#[cfg(feature = "json")]
262	fn generate_sample_json(&self) -> String {
263		format!("\"{}\"", self.display())
264	}
265}