1use core::fmt;
2use std::fmt::Display;
3
4use super::*;
5
6struct WrapDispaly<'a, T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result, SEP: Display>(
7 &'a [T],
8 F,
9 SEP,
11 char,
13 usize,
14);
15impl<T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result, SEP: Display> Display
16 for WrapDispaly<'_, T, F, SEP>
17{
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 for ts in self.0.chunks(self.4) {
20 write!(f, "\n{}", self.2)?;
21 let mut iter = ts.iter();
22 if let Some(first) = iter.next() {
23 self.1(first, f)?;
24 for t in iter {
25 write!(f, "{}", self.3)?;
26 self.1(t, f)?;
27 }
28 }
29 }
30 Ok(())
31 }
32}
33struct InlineDispaly<'a, T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result>(&'a [T], F, char);
34impl<T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result> Display for InlineDispaly<'_, T, F> {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 let mut iter = self.0.iter();
37 if let Some(first) = iter.next() {
38 self.1(first, f)?;
39 for t in iter {
40 write!(f, "{}", self.2)?;
41 self.1(t, f)?;
42 }
43 }
44 Ok(())
45 }
46}
47struct FloatDisplay<'a>(&'a f64);
48impl fmt::Display for FloatDisplay<'_> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 write!(f, "{:.7e}", self.0)
51 }
52}
53
54struct OptionDispaly<'a, T: Display>(&'a Option<T>);
55impl<T: Display> Display for OptionDispaly<'_, T> {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 if let Some(t) = self.0 {
58 write!(f, " {t}")
59 } else {
60 Ok(())
61 }
62 }
63}
64struct MultilineDispaly<'a, T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result>(&'a [T], F);
65impl<T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result> Display for MultilineDispaly<'_, T, F> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 for t in self.0 {
68 write!(f, "\n")?;
69 self.1(t, f)?;
70 }
71 Ok(())
72 }
73}
74
75impl fmt::Display for Value<'_> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 Self::Num(float) => write!(f, "{}", FloatDisplay(float)),
79 Self::Expr(expr) => write!(f, "'{expr}'"),
80 }
81 }
82}
83impl fmt::Display for KeyValue<'_> {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 write!(f, "{}={}", self.k, self.v)
86 }
87}
88
89impl fmt::Display for Token<'_> {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 Self::KV(key_value) => write!(f, "{key_value}"),
93 Self::Value(v) => write!(f, "{v}"),
94 Self::V(name) => write!(f, "V({name})"),
95 Self::I(name) => write!(f, "I({name})"),
96 }
97 }
98}
99
100impl fmt::Display for ModelType<'_> {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 Self::AMP => write!(f, "AMP"),
104 Self::C => write!(f, "C"),
105 Self::CORE => write!(f, "CORE"),
106 Self::D => write!(f, "D"),
107 Self::L => write!(f, "L"),
108 Self::NJF => write!(f, "NJF"),
109 Self::NMOS => write!(f, "NMOS"),
110 Self::NPN => write!(f, "NPN"),
111 Self::OPT => write!(f, "OPT"),
112 Self::PJF => write!(f, "PJF"),
113 Self::PMOS => write!(f, "PMOS"),
114 Self::PNP => write!(f, "PNP"),
115 Self::R => write!(f, "R"),
116 Self::U => write!(f, "U"),
117 Self::W => write!(f, "W"),
118 Self::S => write!(f, "S"),
119 Self::Unknown(span) => write!(f, "{span}"),
120 }
121 }
122}
123
124impl fmt::Display for Data<'_> {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 write!(f, ".DATA {}", self.name)?;
127 match &self.values {
128 DataValues::InlineExpr { params, values } => write!(
129 f,
130 "\n+ {} DATAFORM{}",
131 InlineDispaly(params, Display::fmt, ' '),
132 WrapDispaly(values, Display::fmt, "+ ", ' ', params.len())
133 )?,
134 DataValues::InlineNum { params, values } => write!(
135 f,
136 "\n+ {}{}",
137 InlineDispaly(params, Display::fmt, ' '),
138 WrapDispaly(
139 values,
140 |float: &f64, f: &mut fmt::Formatter<'_>| write!(f, "{}", FloatDisplay(float)),
141 "+ ",
142 ' ',
143 params.len()
144 )
145 )?,
146 DataValues::MER() => todo!(),
147 DataValues::LAM() => todo!(),
148 }
149 write!(f, "\n.ENDDATA")
150 }
151}
152impl fmt::Display for DataValuesCsv<'_, '_> {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 match self.0 {
155 DataValues::InlineExpr { params, values } => write!(
156 f,
157 "{}{}",
158 InlineDispaly(params, Display::fmt, ','),
159 WrapDispaly(values, Display::fmt, "", ',', params.len())
160 ),
161 DataValues::InlineNum { params, values } => write!(
162 f,
163 "{}{}",
164 InlineDispaly(params, Display::fmt, ','),
165 WrapDispaly(
166 values,
167 |float: &f64, f: &mut fmt::Formatter<'_>| write!(f, "{}", FloatDisplay(float)),
168 "",
169 ',',
170 params.len()
171 )
172 ),
173 DataValues::MER() => todo!(),
174 DataValues::LAM() => todo!(),
175 }
176 }
177}
178
179impl fmt::Display for instance::Instance<'_> {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 write!(f, "{}{}", self.name, self.ctx,)
182 }
183}
184
185impl fmt::Display for instance::InstanceCtx<'_> {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 match self {
188 instance::InstanceCtx::Resistor(resistor) => write!(f, "{resistor}"),
189 instance::InstanceCtx::Capacitor(capacitor) => write!(f, "{capacitor}"),
190 instance::InstanceCtx::Inductor(inductor) => write!(f, "{inductor}"),
191 instance::InstanceCtx::Voltage(voltage) => write!(f, "{voltage}"),
192 instance::InstanceCtx::Current(current) => write!(f, "{current}"),
193 instance::InstanceCtx::MOSFET(mosfet) => write!(f, "{mosfet}"),
194 instance::InstanceCtx::BJT(bjt) => write!(f, "{bjt}"),
195 instance::InstanceCtx::Diode(diode) => write!(f, "{diode}"),
196 instance::InstanceCtx::Subckt(subckt) => write!(f, "{subckt}"),
197 instance::InstanceCtx::Unknown {
198 r#type: _,
199 ports,
200 params,
201 } => write!(
202 f,
203 " {} {}",
204 InlineDispaly(ports, Display::fmt, ' '),
205 InlineDispaly(params, Display::fmt, ' ')
206 ),
207 }
208 }
209}
210
211impl fmt::Display for instance::Subckt<'_> {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(
214 f,
215 " {} {} {}",
216 InlineDispaly(&self.ports, Display::fmt, ' '),
217 self.cktname,
218 InlineDispaly(&self.params, Display::fmt, ' ')
219 )
220 }
221}
222
223impl fmt::Display for instance::Voltage<'_> {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 write!(f, "{} {} {}", self.n1, self.n2, self.source,)
226 }
227}
228
229impl fmt::Display for instance::Current<'_> {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(f, "{} {} {}", self.n1, self.n2, self.source,)
232 }
233}
234
235impl fmt::Display for instance::VoltageSource<'_> {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 match self {
238 instance::VoltageSource::Params(params) => {
239 write!(f, " {}", InlineDispaly(params, Display::fmt, ' '))
240 }
241 instance::VoltageSource::Value(value) => write!(f, "{value}"),
242 instance::VoltageSource::PWL(pwl) => write!(f, "{pwl}"),
243 }
244 }
245}
246
247impl fmt::Display for instance::CurrentSource<'_> {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 match self {
250 instance::CurrentSource::Params(params) => {
251 write!(f, " {}", InlineDispaly(params, Display::fmt, ' '))
252 }
253 instance::CurrentSource::Value(value) => write!(f, "{value}"),
254 instance::CurrentSource::PWL(pwl) => write!(f, "{pwl}"),
255 }
256 }
257}
258
259impl fmt::Display for instance::TimeValuePoint<'_> {
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 write!(f, "{} {}", self.time, self.value,)
262 }
263}
264
265impl fmt::Display for instance::PWL<'_> {
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 write!(
268 f,
269 "PWL({})",
270 WrapDispaly(&self.points, Display::fmt, "+ ", ' ', 1),
271 )
272 }
273}
274
275impl fmt::Display for instance::Resistor<'_> {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
278 }
279}
280impl fmt::Display for instance::Capacitor<'_> {
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
283 }
284}
285impl fmt::Display for instance::Inductor<'_> {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
288 }
289}
290
291impl fmt::Display for instance::MOSFET<'_> {
292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293 write!(
294 f,
295 "{} {} {} {} {} {}",
296 self.nd,
297 self.ng,
298 self.ns,
299 OptionDispaly(&self.nb),
300 self.mname,
301 InlineDispaly(&self.params, Display::fmt, ' ')
302 )
303 }
304}
305
306impl fmt::Display for instance::BJT<'_> {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 write!(
309 f,
310 "{} {} {} {} {} {}",
311 self.nc,
312 self.nb,
313 self.ne,
314 OptionDispaly(&self.ns),
315 self.mname,
316 InlineDispaly(&self.params, Display::fmt, ' ')
317 )
318 }
319}
320
321impl fmt::Display for instance::Diode<'_> {
322 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
323 write!(
324 f,
325 "{} {} {} {}",
326 self.nplus,
327 self.nminus,
328 self.mname,
329 InlineDispaly(&self.params, Display::fmt, ' ')
330 )
331 }
332}
333
334impl fmt::Display for Model<'_> {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 write!(
337 f,
338 ".MODEL {} {}{}",
339 self.name,
340 self.model_type,
341 WrapDispaly(&self.params, Display::fmt, "+ ", ' ', 4)
342 )
343 }
344}
345
346impl fmt::Display for Subckt<'_> {
347 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
348 write!(
349 f,
350 ".SUBCKT {} {} {}",
351 self.name,
352 InlineDispaly(&self.ports, Display::fmt, ' '),
353 InlineDispaly(&self.params, Display::fmt, ' ')
354 )?;
355 write!(f, "{}", self.ast)?;
356 write!(f, "\n.ENDS {}", self.name)
357 }
358}
359
360impl fmt::Display for Unknwon<'_> {
361 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
362 write!(
363 f,
364 ".{} {}",
365 self.cmd,
366 InlineDispaly(&self.tokens, Display::fmt, ' ')
367 )
368 }
369}
370impl fmt::Display for General<'_> {
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372 write!(
373 f,
374 ".{} {}",
375 self.cmd,
376 InlineDispaly(&self.tokens, Display::fmt, ' ')
377 )
378 }
379}
380
381impl fmt::Display for AST<'_> {
382 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
383 if !self.option.is_empty() {
384 write!(
385 f,
386 ".OPTION {}",
387 WrapDispaly(
388 &self.option,
389 |option: &(Cow<'_, str>, Option<Value<'_>>), f: &mut fmt::Formatter<'_>| {
390 if let Some(v) = &option.1 {
391 write!(f, "{}={v}", option.0)
392 } else {
393 write!(f, "{}", option.0)
394 }
395 },
396 "+ ",
397 ' ',
398 4
399 )
400 )?;
401 }
402 if !self.param.is_empty() {
403 write!(
404 f,
405 "\n.PARAM {}",
406 WrapDispaly(&self.param, Display::fmt, "+ ", ' ', 4)
407 )?;
408 }
409 write!(f, "{}", MultilineDispaly(&self.model, Display::fmt))?;
410 write!(f, "{}", MultilineDispaly(&self.subckt, Display::fmt))?;
411 write!(f, "{}", MultilineDispaly(&self.instance, Display::fmt))?;
412 write!(
413 f,
414 "{}",
415 MultilineDispaly(
416 &self.init_condition,
417 |ic: &(Cow<'_, str>, Value<'_>, Option<Cow<'_, str>>),
418 f: &mut fmt::Formatter<'_>| {
419 write!(f, ".IC V({})={}", ic.0, ic.1)?;
420 if let Some(subckt) = &ic.2 {
421 write!(f, " suckt={subckt}")
422 } else {
423 Ok(())
424 }
425 },
426 )
427 )?;
428 write!(f, "{}", MultilineDispaly(&self.data, Display::fmt))?;
429 write!(f, "{}", MultilineDispaly(&self.general, Display::fmt))?;
430 write!(f, "{}", MultilineDispaly(&self.unknwon, Display::fmt))?;
431 Ok(())
432 }
433}