netlist_db/lexer/
_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: 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}