netlist_db/
_impl_display.rs

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