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