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, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result>(&'a Option<T>, F);
55impl<T, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result> Display for OptionDispaly<'_, T, F> {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 if let Some(t) = self.0 {
58 self.1(t, f)
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 writeln!(f)?;
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}
123impl fmt::Display for DataFiles<'_> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 write!(
126 f,
127 "{}{}",
128 MultilineDispaly(&self.files, |file, f| write!(
129 f,
130 "+ FILE='{}' {}",
131 file.file,
132 InlineDispaly(
133 &file.pname_col_num,
134 |pname_col_num, f| write!(
135 f,
136 "{}={}",
137 pname_col_num.pname, pname_col_num.col_num
138 ),
139 ' '
140 )
141 )),
142 OptionDispaly(&self.out, |out, f| write!(f, "\n+ OUT='{out}'")),
143 )
144 }
145}
146
147impl fmt::Display for Data<'_> {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 write!(f, ".DATA {}", self.name)?;
150 match &self.values {
151 DataValues::InlineExpr { params, values } => write!(
152 f,
153 "\n+ {} DATAFORM{}",
154 InlineDispaly(params, Display::fmt, ' '),
155 WrapDispaly(values, Display::fmt, "+ ", ' ', params.len())
156 )?,
157 DataValues::InlineNum { params, values } => write!(
158 f,
159 "\n+ {}{}",
160 InlineDispaly(params, Display::fmt, ' '),
161 WrapDispaly(
162 values,
163 |float: &f64, f: &mut fmt::Formatter<'_>| write!(f, "{}", FloatDisplay(float)),
164 "+ ",
165 ' ',
166 params.len()
167 )
168 )?,
169 DataValues::MER(data_files) => write!(f, " MER{data_files}")?,
170 DataValues::LAM(data_files) => write!(f, " LAM{data_files}")?,
171 }
172 write!(f, "\n.ENDDATA")
173 }
174}
175impl fmt::Display for DataValuesCsv<'_, '_> {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 match self.0 {
178 DataValues::InlineExpr { params, values } => write!(
179 f,
180 "{}{}",
181 InlineDispaly(params, Display::fmt, ','),
182 WrapDispaly(values, Display::fmt, "", ',', params.len())
183 ),
184 DataValues::InlineNum { params, values } => write!(
185 f,
186 "{}{}",
187 InlineDispaly(params, Display::fmt, ','),
188 WrapDispaly(
189 values,
190 |float: &f64, f: &mut fmt::Formatter<'_>| write!(f, "{}", FloatDisplay(float)),
191 "",
192 ',',
193 params.len()
194 )
195 ),
196 DataValues::MER(_) => unreachable!(),
197 DataValues::LAM(_) => unreachable!(),
198 }
199 }
200}
201
202impl fmt::Display for instance::Instance<'_> {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 write!(f, "{}{}", self.name, self.ctx,)
205 }
206}
207
208impl fmt::Display for instance::InstanceCtx<'_> {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 match self {
211 instance::InstanceCtx::Resistor(resistor) => write!(f, "{resistor}"),
212 instance::InstanceCtx::Capacitor(capacitor) => write!(f, "{capacitor}"),
213 instance::InstanceCtx::Inductor(inductor) => write!(f, "{inductor}"),
214 instance::InstanceCtx::Voltage(voltage) => write!(f, "{voltage}"),
215 instance::InstanceCtx::Current(current) => write!(f, "{current}"),
216 instance::InstanceCtx::MOSFET(mosfet) => write!(f, "{mosfet}"),
217 instance::InstanceCtx::BJT(bjt) => write!(f, "{bjt}"),
218 instance::InstanceCtx::Diode(diode) => write!(f, "{diode}"),
219 instance::InstanceCtx::Subckt(subckt) => write!(f, "{subckt}"),
220 instance::InstanceCtx::Unknown {
221 r#type: _,
222 ports,
223 params,
224 } => write!(
225 f,
226 " {} {}",
227 InlineDispaly(ports, Display::fmt, ' '),
228 InlineDispaly(params, Display::fmt, ' ')
229 ),
230 }
231 }
232}
233
234impl fmt::Display for instance::Subckt<'_> {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 write!(
237 f,
238 " {} {} {}",
239 InlineDispaly(&self.ports, Display::fmt, ' '),
240 self.cktname,
241 InlineDispaly(&self.params, Display::fmt, ' ')
242 )
243 }
244}
245
246impl fmt::Display for instance::Voltage<'_> {
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248 write!(f, "{} {} {}", self.n1, self.n2, self.source,)
249 }
250}
251
252impl fmt::Display for instance::Current<'_> {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 write!(f, "{} {} {}", self.n1, self.n2, self.source,)
255 }
256}
257
258impl fmt::Display for instance::VoltageSource<'_> {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 match self {
261 instance::VoltageSource::Params(params) => {
262 write!(f, " {}", InlineDispaly(params, Display::fmt, ' '))
263 }
264 instance::VoltageSource::Value(value) => write!(f, "{value}"),
265 instance::VoltageSource::PWL(pwl) => write!(f, "{pwl}"),
266 }
267 }
268}
269
270impl fmt::Display for instance::CurrentSource<'_> {
271 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272 match self {
273 instance::CurrentSource::Params(params) => {
274 write!(f, " {}", InlineDispaly(params, Display::fmt, ' '))
275 }
276 instance::CurrentSource::Value(value) => write!(f, "{value}"),
277 instance::CurrentSource::PWL(pwl) => write!(f, "{pwl}"),
278 }
279 }
280}
281
282impl fmt::Display for instance::TimeValuePoint<'_> {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 write!(f, "{} {}", self.time, self.value,)
285 }
286}
287
288impl fmt::Display for instance::PWL<'_> {
289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 write!(
291 f,
292 "PWL({})",
293 WrapDispaly(&self.points, Display::fmt, "+ ", ' ', 1),
294 )
295 }
296}
297
298impl fmt::Display for instance::Resistor<'_> {
299 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
301 }
302}
303impl fmt::Display for instance::Capacitor<'_> {
304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
306 }
307}
308impl fmt::Display for instance::Inductor<'_> {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 write!(f, "{} {} {}", self.n1, self.n2, self.value,)
311 }
312}
313
314impl fmt::Display for instance::MOSFET<'_> {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 write!(
317 f,
318 "{} {} {} {} {} {}",
319 self.nd,
320 self.ng,
321 self.ns,
322 OptionDispaly(&self.nb, |nb, f| write!(f, " {nb}")),
323 self.mname,
324 InlineDispaly(&self.params, Display::fmt, ' ')
325 )
326 }
327}
328
329impl fmt::Display for instance::BJT<'_> {
330 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331 write!(
332 f,
333 "{} {} {} {} {} {}",
334 self.nc,
335 self.nb,
336 self.ne,
337 OptionDispaly(&self.ns, |ns, f| write!(f, " {ns}")),
338 self.mname,
339 InlineDispaly(&self.params, Display::fmt, ' ')
340 )
341 }
342}
343
344impl fmt::Display for instance::Diode<'_> {
345 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346 write!(
347 f,
348 "{} {} {} {}",
349 self.nplus,
350 self.nminus,
351 self.mname,
352 InlineDispaly(&self.params, Display::fmt, ' ')
353 )
354 }
355}
356
357impl fmt::Display for Model<'_> {
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 write!(
360 f,
361 ".MODEL {} {}{}",
362 self.name,
363 self.model_type,
364 WrapDispaly(&self.params, Display::fmt, "+ ", ' ', 4)
365 )
366 }
367}
368
369impl fmt::Display for Subckt<'_> {
370 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371 write!(
372 f,
373 ".SUBCKT {} {} {}",
374 self.name,
375 InlineDispaly(&self.ports, Display::fmt, ' '),
376 InlineDispaly(&self.params, Display::fmt, ' ')
377 )?;
378 write!(f, "{}", self.ast)?;
379 write!(f, "\n.ENDS {}", self.name)
380 }
381}
382
383impl fmt::Display for Unknwon<'_> {
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 write!(
386 f,
387 ".{} {}",
388 self.cmd,
389 InlineDispaly(&self.tokens, Display::fmt, ' ')
390 )
391 }
392}
393impl fmt::Display for General<'_> {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 write!(
396 f,
397 ".{} {}",
398 self.cmd,
399 InlineDispaly(&self.tokens, Display::fmt, ' ')
400 )
401 }
402}
403
404impl fmt::Display for AST<'_> {
405 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406 if !self.option.is_empty() {
407 write!(
408 f,
409 ".OPTION {}",
410 WrapDispaly(
411 &self.option,
412 |option: &(Cow<'_, str>, Option<Value<'_>>), f: &mut fmt::Formatter<'_>| {
413 if let Some(v) = &option.1 {
414 write!(f, "{}={v}", option.0)
415 } else {
416 write!(f, "{}", option.0)
417 }
418 },
419 "+ ",
420 ' ',
421 4
422 )
423 )?;
424 }
425 if !self.param.is_empty() {
426 write!(
427 f,
428 "\n.PARAM {}",
429 WrapDispaly(&self.param, Display::fmt, "+ ", ' ', 4)
430 )?;
431 }
432 write!(f, "{}", MultilineDispaly(&self.model, Display::fmt))?;
433 write!(f, "{}", MultilineDispaly(&self.subckt, Display::fmt))?;
434 write!(f, "{}", MultilineDispaly(&self.instance, Display::fmt))?;
435 write!(
436 f,
437 "{}",
438 MultilineDispaly(
439 &self.init_condition,
440 |ic: &(Cow<'_, str>, Value<'_>, Option<Cow<'_, str>>),
441 f: &mut fmt::Formatter<'_>| {
442 write!(f, ".IC V({})={}", ic.0, ic.1)?;
443 if let Some(subckt) = &ic.2 {
444 write!(f, " suckt={subckt}")
445 } else {
446 Ok(())
447 }
448 },
449 )
450 )?;
451 write!(
452 f,
453 "{}",
454 MultilineDispaly(
455 &self.nodeset,
456 |ic: &(Cow<'_, str>, Value<'_>, Option<Cow<'_, str>>),
457 f: &mut fmt::Formatter<'_>| {
458 write!(f, ".NODESET {}={}", ic.0, ic.1)?;
459 if let Some(subckt) = &ic.2 {
460 write!(f, " suckt={subckt}")
461 } else {
462 Ok(())
463 }
464 },
465 )
466 )?;
467 write!(f, "{}", MultilineDispaly(&self.data, Display::fmt))?;
468 write!(f, "{}", MultilineDispaly(&self.general, Display::fmt))?;
469 write!(f, "{}", MultilineDispaly(&self.unknwon, Display::fmt))?;
470 Ok(())
471 }
472}