netlist_db/
_impl_display.rs

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    /// line sep
10    SEP,
11    /// item sep
12    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}