esexpr/
expr.rs

1use alloc::borrow::{Cow, ToOwned};
2use alloc::collections::BTreeMap;
3use alloc::vec::Vec;
4use core::fmt::{Debug, Formatter};
5
6use half::f16;
7use num_bigint::{BigInt, BigUint};
8
9use crate::cowstr::CowStr;
10use crate::{DecodeError, ESExprCodec, ESExprEncodedEq, ESExprTag, ESExprTagSet};
11
12/// Representation of an `ESExpr` value.
13/// Must be a constructor, bool, int, string, float32, float64, {int,uint}{8,16,32,64} or null.
14#[derive(Debug, Clone)]
15pub enum ESExpr<'a> {
16	/// A constructor expression.
17	/// Can contain positional and keyword arguments.
18	Constructor(ESExprConstructor<'a>),
19
20	/// A bool value.
21	Bool(bool),
22
23	/// An integer value.
24	Int(Cow<'a, BigInt>),
25
26	/// A string value.
27	Str(CowStr<'a>),
28
29	/// A float16 value.
30	Float16(f16),
31
32	/// A float32 value.
33	Float32(f32),
34
35	/// A float64 value.
36	Float64(f64),
37
38	/// An array of 8-bit values
39	Array8(Cow<'a, [u8]>),
40
41	/// An array of 16-bit values
42	Array16(Cow<'a, [u16]>),
43
44	/// An array of 32-bit values
45	Array32(Cow<'a, [u32]>),
46
47	/// An array of 64-bit values
48	Array64(Cow<'a, [u64]>),
49
50	/// An array of 128-bit values
51	Array128(Cow<'a, [u128]>),
52
53	/// A Null value.
54	Null(Cow<'a, BigUint>),
55}
56
57impl<'a> ESExpr<'a> {
58	/// Create a new constructor expression
59	pub fn constructor<'b, S: Into<CowStr<'b>>, A: Into<ConstructorArgs<'a>>, K: Into<KeywordArgs<'a>>>(
60		name: S,
61		args: A,
62		kwargs: K,
63	) -> Self
64	where
65		'b: 'a,
66	{
67		ESExpr::Constructor(ESExprConstructor {
68			name: name.into(),
69			args: args.into(),
70			kwargs: kwargs.into(),
71		})
72	}
73
74	/// Get the tag of an expression.
75	#[must_use]
76	pub fn tag<'b>(&'b self) -> ESExprTag<'b> {
77		match self {
78			ESExpr::Constructor(ESExprConstructor { name, .. }) => ESExprTag::Constructor(name.as_borrowed()),
79			ESExpr::Bool(_) => ESExprTag::Bool,
80			ESExpr::Int(_) => ESExprTag::Int,
81			ESExpr::Str(_) => ESExprTag::Str,
82			ESExpr::Float16(_) => ESExprTag::Float16,
83			ESExpr::Float32(_) => ESExprTag::Float32,
84			ESExpr::Float64(_) => ESExprTag::Float64,
85			ESExpr::Array8(_) => ESExprTag::Array8,
86			ESExpr::Array16(_) => ESExprTag::Array16,
87			ESExpr::Array32(_) => ESExprTag::Array32,
88			ESExpr::Array64(_) => ESExprTag::Array64,
89			ESExpr::Array128(_) => ESExprTag::Array128,
90			ESExpr::Null(_) => ESExprTag::Null,
91		}
92	}
93
94	/// Performs a deep clone of the value.
95	#[must_use]
96	pub fn as_owned(&self) -> ESExpr<'static> {
97		match self {
98			ESExpr::Constructor(constructor) => ESExpr::Constructor(constructor.as_owned()),
99			&ESExpr::Bool(b) => ESExpr::Bool(b),
100			ESExpr::Int(i) => ESExpr::Int(Cow::Owned(i.as_ref().clone())),
101			ESExpr::Str(s) => ESExpr::Str(s.as_owned_cowstr()),
102			&ESExpr::Float16(f) => ESExpr::Float16(f),
103			&ESExpr::Float32(f) => ESExpr::Float32(f),
104			&ESExpr::Float64(f) => ESExpr::Float64(f),
105			ESExpr::Array8(b) => ESExpr::Array8(Cow::Owned(b.as_ref().to_owned())),
106			ESExpr::Array16(b) => ESExpr::Array16(Cow::Owned(b.as_ref().to_owned())),
107			ESExpr::Array32(b) => ESExpr::Array32(Cow::Owned(b.as_ref().to_owned())),
108			ESExpr::Array64(b) => ESExpr::Array64(Cow::Owned(b.as_ref().to_owned())),
109			ESExpr::Array128(b) => ESExpr::Array128(Cow::Owned(b.as_ref().to_owned())),
110			ESExpr::Null(level) => ESExpr::Null(Cow::Owned(level.as_ref().clone())),
111		}
112	}
113
114	/// Ensures that any borrowed values are converted to owned values.
115	#[must_use]
116	pub fn into_owned(self) -> ESExpr<'static> {
117		match self {
118			ESExpr::Constructor(constructor) => ESExpr::Constructor(constructor.into_owned()),
119			ESExpr::Bool(b) => ESExpr::Bool(b),
120			ESExpr::Int(i) => ESExpr::Int(Cow::Owned(i.into_owned())),
121			ESExpr::Str(s) => ESExpr::Str(s.into_owned_cowstr()),
122			ESExpr::Float16(f) => ESExpr::Float16(f),
123			ESExpr::Float32(f) => ESExpr::Float32(f),
124			ESExpr::Float64(f) => ESExpr::Float64(f),
125			ESExpr::Array8(b) => ESExpr::Array8(Cow::Owned(b.into_owned())),
126			ESExpr::Array16(b) => ESExpr::Array16(Cow::Owned(b.into_owned())),
127			ESExpr::Array32(b) => ESExpr::Array32(Cow::Owned(b.into_owned())),
128			ESExpr::Array64(b) => ESExpr::Array64(Cow::Owned(b.into_owned())),
129			ESExpr::Array128(b) => ESExpr::Array128(Cow::Owned(b.into_owned())),
130			ESExpr::Null(level) => ESExpr::Null(Cow::Owned(level.into_owned())),
131		}
132	}
133
134	/// Creates an `ESExpr` value from a reference without making a deep copy.
135	#[must_use]
136	pub fn as_borrowed<'b>(&'b self) -> ESExpr<'b>
137	where
138		'a: 'b,
139	{
140		match self {
141			ESExpr::Constructor(constructor) => ESExpr::Constructor(constructor.as_borrowed()),
142			&ESExpr::Bool(b) => ESExpr::Bool(b),
143			ESExpr::Int(i) => ESExpr::Int(Cow::Borrowed(i.as_ref())),
144			ESExpr::Str(s) => ESExpr::Str(s.as_borrowed()),
145			&ESExpr::Float16(f) => ESExpr::Float16(f),
146			&ESExpr::Float32(f) => ESExpr::Float32(f),
147			&ESExpr::Float64(f) => ESExpr::Float64(f),
148			ESExpr::Array8(b) => ESExpr::Array8(Cow::Borrowed(b.as_ref())),
149			ESExpr::Array16(b) => ESExpr::Array16(Cow::Borrowed(b.as_ref())),
150			ESExpr::Array32(b) => ESExpr::Array32(Cow::Borrowed(b.as_ref())),
151			ESExpr::Array64(b) => ESExpr::Array64(Cow::Borrowed(b.as_ref())),
152			ESExpr::Array128(b) => ESExpr::Array128(Cow::Borrowed(b.as_ref())),
153			ESExpr::Null(level) => ESExpr::Null(Cow::Borrowed(level.as_ref())),
154		}
155	}
156}
157
158impl<'a, 'b> PartialEq<ESExpr<'b>> for ESExpr<'a> {
159	fn eq(&self, other: &ESExpr<'b>) -> bool {
160		match self {
161			ESExpr::Constructor(ESExprConstructor {
162				name: name1,
163				args: args1,
164				kwargs: kwargs1,
165			}) => {
166				let ESExpr::Constructor(ESExprConstructor {
167					name: name2,
168					args: args2,
169					kwargs: kwargs2,
170				}) = other
171				else {
172					return false;
173				};
174
175				name1 == name2 &&
176					args1 == args2 && kwargs1
177					.iter()
178					.zip(kwargs2.iter())
179					.all(|((k1, v1), (k2, v2))| k1 == k2 && v1 == v2)
180			},
181			&ESExpr::Bool(b1) => matches!(other, &ESExpr::Bool(b2) if b1 == b2),
182			ESExpr::Int(i1) => matches!(other, ESExpr::Int(i2) if i1 == i2),
183			ESExpr::Str(s1) => matches!(other, ESExpr::Str(s2) if s1 == s2),
184			&ESExpr::Float16(f1) => matches!(other, &ESExpr::Float16(f2) if f1.to_bits() == f2.to_bits()),
185			&ESExpr::Float32(f1) => matches!(other, &ESExpr::Float32(f2) if f1.to_bits() == f2.to_bits()),
186			&ESExpr::Float64(f1) => matches!(other, &ESExpr::Float64(f2) if f1.to_bits() == f2.to_bits()),
187			ESExpr::Array8(a1) => matches!(other, ESExpr::Array8(a2) if a1 == a2),
188			ESExpr::Array16(a1) => matches!(other, ESExpr::Array16(a2) if a1 == a2),
189			ESExpr::Array32(a1) => matches!(other, ESExpr::Array32(a2) if a1 == a2),
190			ESExpr::Array64(a1) => matches!(other, ESExpr::Array64(a2) if a1 == a2),
191			ESExpr::Array128(a1) => matches!(other, ESExpr::Array128(a2) if a1 == a2),
192			ESExpr::Null(l1) => matches!(other, ESExpr::Null(l2) if l1 == l2),
193		}
194	}
195}
196
197impl<'a> Eq for ESExpr<'a> {}
198
199impl<'a> ESExprEncodedEq for ESExpr<'a> {
200	fn is_encoded_eq(&self, other: &Self) -> bool {
201		self == other
202	}
203}
204
205
206impl<'a> ESExprCodec<'a> for ESExpr<'a> {
207	const TAGS: ESExprTagSet = ESExprTagSet::All;
208
209	fn encode_esexpr(&'a self) -> ESExpr<'a> {
210		self.as_borrowed()
211	}
212
213	fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
214		Ok(expr)
215	}
216}
217
218/// A wrapper for a `ESExpr<'static>`
219#[derive(Debug, Clone, PartialEq, Eq)]
220pub struct ESExprStatic(ESExpr<'static>);
221
222impl ESExprStatic {
223	/// Create an `ESExprStatic`
224	pub fn new(e: ESExpr<'static>) -> Self {
225		ESExprStatic(e)
226	}
227	
228	/// Get the underlying `ESExpr`.
229	pub fn into_inner(self) -> ESExpr<'static> {
230		self.0
231	}
232}
233
234impl ESExprEncodedEq for ESExprStatic {
235	fn is_encoded_eq(&self, other: &Self) -> bool {
236		self == other
237	}
238}
239
240impl<'a> ESExprCodec<'a> for ESExprStatic {
241	const TAGS: ESExprTagSet = ESExprTagSet::All;
242
243	fn encode_esexpr(&'a self) -> ESExpr<'a> {
244		self.0.as_borrowed()
245	}
246
247	fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
248		Ok(ESExprStatic(expr.into_owned()))
249	}
250}
251
252/// A `ESExpr` constructor expression
253#[derive(Debug, Clone, PartialEq, Eq)]
254pub struct ESExprConstructor<'a> {
255	/// The name of the constructor.
256	pub name: CowStr<'a>,
257
258	/// The constructor's positional arguments.
259	pub args: ConstructorArgs<'a>,
260
261	/// The constructor's keyword arguments.
262	pub kwargs: KeywordArgs<'a>,
263}
264
265impl<'a> ESExprConstructor<'a> {
266	fn into_owned(self) -> ESExprConstructor<'static> {
267		ESExprConstructor {
268			name: self.name.as_owned_cowstr(),
269			args: self.args.into_owned(),
270			kwargs: self.kwargs.into_owned(),
271		}
272	}
273
274	fn as_owned(&self) -> ESExprConstructor<'static> {
275		ESExprConstructor {
276			name: self.name.as_owned_cowstr(),
277			args: self.args.as_owned(),
278			kwargs: self.kwargs.as_owned(),
279		}
280	}
281
282	fn as_borrowed<'b>(&'b self) -> ESExprConstructor<'b> {
283		ESExprConstructor {
284			name: self.name.as_borrowed(),
285			args: self.args.as_borrowed(),
286			kwargs: self.kwargs.as_borrowed(),
287		}
288	}
289}
290
291/// Positional arguments of an `ESExprConstructor`.
292#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct ConstructorArgs<'a> {
294	args: ConstructorArgsInner<'a>,
295}
296
297impl<'a> ConstructorArgs<'a> {
298	/// Iterates over constructor arguments.
299	pub fn iter(&'a self) -> ConstructorArgsIntoIter<'a> {
300		self.as_borrowed().into_iter()
301	}
302
303	/// The number of constructor arguments.
304	#[must_use]
305	pub fn len(&self) -> usize {
306		self.args.as_slice().len()
307	}
308
309	/// Gets whether there are any arguments.
310	#[must_use]
311	pub fn is_empty(&self) -> bool {
312		self.args.as_slice().is_empty()
313	}
314
315	fn into_owned(self) -> ConstructorArgs<'static> {
316		ConstructorArgs {
317			args: ConstructorArgsInner::Owned(self.into_iter().map(ESExpr::into_owned).collect()),
318		}
319	}
320
321	fn as_owned(&self) -> ConstructorArgs<'static> {
322		ConstructorArgs {
323			args: ConstructorArgsInner::Owned(self.into_iter().map(ESExpr::into_owned).collect()),
324		}
325	}
326
327	fn as_borrowed(&self) -> ConstructorArgs {
328		ConstructorArgs {
329			args: match &self.args {
330				ConstructorArgsInner::Owned(args) => ConstructorArgsInner::Borrowed(args),
331				ConstructorArgsInner::Borrowed(args) => ConstructorArgsInner::Borrowed(args),
332			},
333		}
334	}
335}
336
337impl<'a> From<Vec<ESExpr<'a>>> for ConstructorArgs<'a> {
338	fn from(args: Vec<ESExpr<'a>>) -> Self {
339		ConstructorArgs {
340			args: ConstructorArgsInner::Owned(args),
341		}
342	}
343}
344
345impl<'a> From<&'a [ESExpr<'a>]> for ConstructorArgs<'a> {
346	fn from(args: &'a [ESExpr<'a>]) -> Self {
347		ConstructorArgs {
348			args: ConstructorArgsInner::Borrowed(args),
349		}
350	}
351}
352
353impl<'a, const N: usize> From<[ESExpr<'a>; N]> for ConstructorArgs<'a> {
354	fn from(args: [ESExpr<'a>; N]) -> Self {
355		ConstructorArgs {
356			args: ConstructorArgsInner::Owned(args.to_vec()),
357		}
358	}
359}
360
361impl<'a> From<ConstructorArgs<'a>> for Vec<ESExpr<'a>> {
362	fn from(args: ConstructorArgs<'a>) -> Self {
363		match args.args {
364			ConstructorArgsInner::Owned(args) => args,
365			ConstructorArgsInner::Borrowed(args) => args.iter().map(ESExpr::as_borrowed).collect(),
366		}
367	}
368}
369
370impl<'a> IntoIterator for ConstructorArgs<'a> {
371	type Item = ESExpr<'a>;
372	type IntoIter = ConstructorArgsIntoIter<'a>;
373
374	fn into_iter(self) -> Self::IntoIter {
375		ConstructorArgsIntoIter {
376			inner_iter: match self.args {
377				ConstructorArgsInner::Owned(args) => ConstructorArgsInnerIntoIter::Owned(args.into_iter()),
378				ConstructorArgsInner::Borrowed(args) => ConstructorArgsInnerIntoIter::Borrowed(args.iter()),
379			},
380		}
381	}
382}
383
384impl<'a> IntoIterator for &'a ConstructorArgs<'a> {
385	type Item = ESExpr<'a>;
386	type IntoIter = ConstructorArgsIntoIter<'a>;
387
388	fn into_iter(self) -> Self::IntoIter {
389		self.as_borrowed().into_iter()
390	}
391}
392
393/// `ESExpr` Constructor arguments
394/// Used instead of `Cow` because of lifetime variance.
395#[derive(Clone)]
396enum ConstructorArgsInner<'a> {
397	/// Constructor arguments owned by this constructor.
398	Owned(Vec<ESExpr<'a>>),
399
400	/// Constructor arguments borrowed from another constructor.
401	Borrowed(&'a [ESExpr<'a>]),
402}
403
404impl<'a> ConstructorArgsInner<'a> {
405	fn as_slice(&self) -> &[ESExpr<'a>] {
406		match self {
407			ConstructorArgsInner::Owned(args) => args,
408			ConstructorArgsInner::Borrowed(args) => args,
409		}
410	}
411}
412
413impl<'a> Debug for ConstructorArgsInner<'a> {
414	fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
415		self.as_slice().fmt(f)
416	}
417}
418
419impl<'a> PartialEq for ConstructorArgsInner<'a> {
420	fn eq(&self, other: &Self) -> bool {
421		self.as_slice() == other.as_slice()
422	}
423}
424
425impl<'a> Eq for ConstructorArgsInner<'a> {}
426
427#[must_use]
428pub struct ConstructorArgsIntoIter<'a> {
429	inner_iter: ConstructorArgsInnerIntoIter<'a>,
430}
431
432impl<'a> Iterator for ConstructorArgsIntoIter<'a> {
433	type Item = ESExpr<'a>;
434
435	fn next(&mut self) -> Option<Self::Item> {
436		self.inner_iter.next()
437	}
438}
439
440enum ConstructorArgsInnerIntoIter<'a> {
441	Owned(alloc::vec::IntoIter<ESExpr<'a>>),
442	Borrowed(alloc::slice::Iter<'a, ESExpr<'a>>),
443}
444
445impl<'a> Iterator for ConstructorArgsInnerIntoIter<'a> {
446	type Item = ESExpr<'a>;
447
448	fn next(&mut self) -> Option<Self::Item> {
449		match self {
450			ConstructorArgsInnerIntoIter::Owned(iter) => iter.next(),
451			ConstructorArgsInnerIntoIter::Borrowed(iter) => iter.next().map(ESExpr::as_borrowed),
452		}
453	}
454}
455
456/// `ESExpr` constructor keyword arguments
457#[derive(Clone, Debug, PartialEq, Eq)]
458pub struct KeywordArgs<'a> {
459	kwargs: KeywordArgsInner<'a>,
460}
461
462impl<'a> KeywordArgs<'a> {
463	/// Iterate keyword arguments
464	pub fn iter(&'a self) -> KeywordArgsIntoIter<'a> {
465		self.into_iter()
466	}
467
468	/// The number of keyword arguments.
469	#[must_use]
470	pub fn len(&self) -> usize {
471		self.kwargs.as_map().len()
472	}
473
474	/// Checks if there are any keyword arguments
475	#[must_use]
476	pub fn is_empty(&self) -> bool {
477		self.kwargs.as_map().is_empty()
478	}
479
480	fn into_owned(self) -> KeywordArgs<'static> {
481		KeywordArgs {
482			kwargs: KeywordArgsInner::Owned(
483				self.into_iter()
484					.map(|(k, v)| (k.into_owned_cowstr(), v.into_owned()))
485					.collect(),
486			),
487		}
488	}
489
490	fn as_owned(&self) -> KeywordArgs<'static> {
491		KeywordArgs {
492			kwargs: KeywordArgsInner::Owned(
493				self.iter()
494					.map(|(k, v)| (k.into_owned_cowstr(), v.into_owned()))
495					.collect(),
496			),
497		}
498	}
499
500	fn as_borrowed(&self) -> KeywordArgs {
501		KeywordArgs {
502			kwargs: match &self.kwargs {
503				KeywordArgsInner::Owned(kwargs) => KeywordArgsInner::Borrowed(kwargs),
504				KeywordArgsInner::Borrowed(kwargs) => KeywordArgsInner::Borrowed(kwargs),
505			},
506		}
507	}
508}
509
510impl<'a> From<BTreeMap<CowStr<'a>, ESExpr<'a>>> for KeywordArgs<'a> {
511	fn from(kwargs: BTreeMap<CowStr<'a>, ESExpr<'a>>) -> Self {
512		KeywordArgs {
513			kwargs: KeywordArgsInner::Owned(kwargs),
514		}
515	}
516}
517
518impl<'a> From<&'a BTreeMap<CowStr<'a>, ESExpr<'a>>> for KeywordArgs<'a> {
519	fn from(kwargs: &'a BTreeMap<CowStr<'a>, ESExpr<'a>>) -> Self {
520		KeywordArgs {
521			kwargs: KeywordArgsInner::Borrowed(kwargs),
522		}
523	}
524}
525
526impl<'a, const N: usize> From<[(CowStr<'a>, ESExpr<'a>); N]> for KeywordArgs<'a> {
527	fn from(value: [(CowStr<'a>, ESExpr<'a>); N]) -> Self {
528		KeywordArgs {
529			kwargs: KeywordArgsInner::Owned(BTreeMap::from(value)),
530		}
531	}
532}
533
534impl<'a> From<KeywordArgs<'a>> for BTreeMap<CowStr<'a>, ESExpr<'a>> {
535	fn from(kwargs: KeywordArgs<'a>) -> Self {
536		match kwargs.kwargs {
537			KeywordArgsInner::Owned(kwargs) => kwargs,
538			KeywordArgsInner::Borrowed(kwargs) => {
539				kwargs.iter().map(|(k, v)| (k.as_owned_cowstr(), v.clone())).collect()
540			},
541		}
542	}
543}
544
545impl<'a> IntoIterator for KeywordArgs<'a> {
546	type Item = (CowStr<'a>, ESExpr<'a>);
547	type IntoIter = KeywordArgsIntoIter<'a>;
548
549	fn into_iter(self) -> Self::IntoIter {
550		KeywordArgsIntoIter {
551			inner_iter: match self.kwargs {
552				KeywordArgsInner::Owned(kwargs) => KeywordArgsInnerIntoIter::Owned(kwargs.into_iter()),
553				KeywordArgsInner::Borrowed(kwargs) => KeywordArgsInnerIntoIter::Borrowed(kwargs.iter()),
554			},
555		}
556	}
557}
558
559impl<'a> IntoIterator for &'a KeywordArgs<'a> {
560	type Item = (CowStr<'a>, ESExpr<'a>);
561	type IntoIter = KeywordArgsIntoIter<'a>;
562
563	fn into_iter(self) -> Self::IntoIter {
564		self.as_borrowed().into_iter()
565	}
566}
567
568#[derive(Clone)]
569pub enum KeywordArgsInner<'a> {
570	Owned(BTreeMap<CowStr<'a>, ESExpr<'a>>),
571	Borrowed(&'a BTreeMap<CowStr<'a>, ESExpr<'a>>),
572}
573
574impl<'a> KeywordArgsInner<'a> {
575	fn as_map(&self) -> &BTreeMap<CowStr<'a>, ESExpr<'a>> {
576		match self {
577			KeywordArgsInner::Owned(kwargs) => kwargs,
578			KeywordArgsInner::Borrowed(kwargs) => kwargs,
579		}
580	}
581}
582
583impl<'a> Debug for KeywordArgsInner<'a> {
584	fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
585		self.as_map().fmt(f)
586	}
587}
588
589impl<'a> PartialEq for KeywordArgsInner<'a> {
590	fn eq(&self, other: &Self) -> bool {
591		self.as_map() == other.as_map()
592	}
593}
594
595impl<'a> Eq for KeywordArgsInner<'a> {}
596
597#[must_use]
598pub struct KeywordArgsIntoIter<'a> {
599	inner_iter: KeywordArgsInnerIntoIter<'a>,
600}
601
602impl<'a> Iterator for KeywordArgsIntoIter<'a> {
603	type Item = (CowStr<'a>, ESExpr<'a>);
604
605	fn next(&mut self) -> Option<Self::Item> {
606		self.inner_iter.next()
607	}
608}
609
610enum KeywordArgsInnerIntoIter<'a> {
611	Owned(alloc::collections::btree_map::IntoIter<CowStr<'a>, ESExpr<'a>>),
612	Borrowed(alloc::collections::btree_map::Iter<'a, CowStr<'a>, ESExpr<'a>>),
613}
614
615impl<'a> Iterator for KeywordArgsInnerIntoIter<'a> {
616	type Item = (CowStr<'a>, ESExpr<'a>);
617
618	fn next(&mut self) -> Option<Self::Item> {
619		match self {
620			KeywordArgsInnerIntoIter::Owned(iter) => iter.next(),
621			KeywordArgsInnerIntoIter::Borrowed(iter) => {
622				iter.next().map(|(k, v)| (k.as_borrowed(), ESExpr::as_borrowed(v)))
623			},
624		}
625	}
626}