netlist_db/
_impl_display.rs

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