webidl_utils/extend/
types.rs

1use crate::extend::ExtendGenerics;
2use weedle::common::Generics;
3use weedle::term::*;
4use weedle::types::*;
5
6/// Extension methods for `MayBeNull<T>`
7pub trait ExtendMayBeNull<T> {
8	fn new(type_: T, q_mark: Option<QMark>) -> Self;
9	fn new_optional(type_: T) -> Self;
10	fn new_required(type_: T) -> Self;
11	fn is_optional(&self) -> bool;
12	fn is_required(&self) -> bool;
13}
14
15impl<T> ExtendMayBeNull<T> for MayBeNull<T> {
16	fn new(type_: T, q_mark: Option<QMark>) -> Self {
17		Self { type_, q_mark }
18	}
19
20	fn new_optional(type_: T) -> Self {
21		Self::new(type_, Some(QMark))
22	}
23
24	fn new_required(type_: T) -> Self {
25		Self::new(type_, None)
26	}
27
28	fn is_optional(&self) -> bool {
29		self.q_mark.is_some()
30	}
31
32	fn is_required(&self) -> bool {
33		self.q_mark.is_none()
34	}
35}
36
37/// Extension methods for floating point types
38pub trait ExtendFloatingPointType {
39	fn unrestricted(&self) -> Option<Unrestricted>;
40}
41
42/// Extension methods for creating floating point types
43pub trait ExtendFloatingPointTypeNew {
44	type FloatType;
45	fn new(unrestricted: Option<Unrestricted>, ty: Self::FloatType) -> Self;
46	fn new_unrestricted() -> Self;
47	fn new_restricted() -> Self;
48}
49
50impl ExtendFloatingPointType for FloatingPointType {
51	fn unrestricted(&self) -> Option<Unrestricted> {
52		match self {
53			Self::Float(f) => f.unrestricted,
54			Self::Double(f) => f.unrestricted,
55		}
56	}
57}
58
59impl ExtendFloatingPointType for DoubleType {
60	fn unrestricted(&self) -> Option<Unrestricted> {
61		self.unrestricted
62	}
63}
64
65impl ExtendFloatingPointTypeNew for DoubleType {
66	type FloatType = Double;
67
68	fn new(unrestricted: Option<Unrestricted>, ty: Self::FloatType) -> Self {
69		Self {
70			unrestricted,
71			double: ty,
72		}
73	}
74
75	fn new_unrestricted() -> Self {
76		Self::new(Some(Unrestricted), Double)
77	}
78
79	fn new_restricted() -> Self {
80		Self::new(None, Double)
81	}
82}
83
84impl ExtendFloatingPointType for FloatType {
85	fn unrestricted(&self) -> Option<Unrestricted> {
86		self.unrestricted
87	}
88}
89
90impl ExtendFloatingPointTypeNew for FloatType {
91	type FloatType = Float;
92
93	fn new(unrestricted: Option<Unrestricted>, ty: Self::FloatType) -> Self {
94		Self {
95			unrestricted,
96			float: ty,
97		}
98	}
99
100	fn new_unrestricted() -> Self {
101		Self::new(Some(Unrestricted), Float)
102	}
103
104	fn new_restricted() -> Self {
105		Self::new(None, Float)
106	}
107}
108
109/// Extension methods for integer types
110pub trait ExtendIntegerType {
111	fn unsigned(&self) -> Option<Unsigned>;
112}
113
114/// Extension methods for creating integer types
115pub trait ExtendIntegerTypeNew {
116	type IntegerType;
117	fn new(unsigned: Option<Unsigned>, ty: Self::IntegerType) -> Self;
118	fn new_signed() -> Self;
119	fn new_unsigned() -> Self;
120}
121
122impl ExtendIntegerType for IntegerType {
123	fn unsigned(&self) -> Option<Unsigned> {
124		match self {
125			Self::Short(i) => i.unsigned,
126			Self::Long(i) => i.unsigned,
127			Self::LongLong(i) => i.unsigned,
128		}
129	}
130}
131
132impl ExtendIntegerType for ShortType {
133	fn unsigned(&self) -> Option<Unsigned> {
134		self.unsigned
135	}
136}
137
138impl ExtendIntegerTypeNew for ShortType {
139	type IntegerType = Short;
140
141	fn new(unsigned: Option<Unsigned>, short: Self::IntegerType) -> Self {
142		Self { unsigned, short }
143	}
144
145	fn new_signed() -> Self {
146		Self::new(None, Short)
147	}
148
149	fn new_unsigned() -> Self {
150		Self::new(Some(Unsigned), Short)
151	}
152}
153
154impl ExtendIntegerType for LongType {
155	fn unsigned(&self) -> Option<Unsigned> {
156		self.unsigned
157	}
158}
159
160impl ExtendIntegerTypeNew for LongType {
161	type IntegerType = Long;
162
163	fn new(unsigned: Option<Unsigned>, long: Self::IntegerType) -> Self {
164		Self { unsigned, long }
165	}
166
167	fn new_signed() -> Self {
168		Self::new(None, Long)
169	}
170
171	fn new_unsigned() -> Self {
172		Self::new(Some(Unsigned), Long)
173	}
174}
175
176impl ExtendIntegerType for LongLongType {
177	fn unsigned(&self) -> Option<Unsigned> {
178		self.unsigned
179	}
180}
181
182impl ExtendIntegerTypeNew for LongLongType {
183	type IntegerType = (Long, Long);
184
185	#[rustfmt::skip]
186	fn new(unsigned: Option<Unsigned>, long_long: Self::IntegerType) -> Self {
187		Self { unsigned, long_long }
188	}
189
190	fn new_signed() -> Self {
191		Self::new(None, (Long, Long))
192	}
193
194	fn new_unsigned() -> Self {
195		Self::new(Some(Unsigned), (Long, Long))
196	}
197}
198
199/// Extension methods for `PromiseType`
200pub trait ExtendPromiseType<'a> {
201	fn new(ty: ReturnType<'a>) -> Self;
202}
203
204impl<'a> ExtendPromiseType<'a> for PromiseType<'a> {
205	fn new(ty: ReturnType<'a>) -> Self {
206		Self {
207			promise: Promise,
208			generics: Generics::new(Box::new(ty)),
209		}
210	}
211}
212
213/// Extension methods for `SequenceType`
214pub trait ExtendSequenceType<'a> {
215	fn new(ty: Type<'a>) -> Self;
216}
217
218impl<'a> ExtendSequenceType<'a> for SequenceType<'a> {
219	fn new(ty: Type<'a>) -> Self {
220		Self {
221			sequence: Sequence,
222			generics: Generics::new(Box::new(ty)),
223		}
224	}
225}
226
227/// Extension methods for `FrozenArrayType`
228pub trait ExtendFrozenArrayType<'a> {
229	fn new(ty: Type<'a>) -> Self;
230}
231
232impl<'a> ExtendFrozenArrayType<'a> for FrozenArrayType<'a> {
233	fn new(ty: Type<'a>) -> Self {
234		Self {
235			frozen_array: FrozenArray,
236			generics: Generics::new(Box::new(ty)),
237		}
238	}
239}
240
241/// Extension methods for `RecordType`
242pub trait ExtendRecordType<'a> {
243	fn new(key: RecordKeyType<'a>, value: Type<'a>) -> Self;
244}
245
246impl<'a> ExtendRecordType<'a> for RecordType<'a> {
247	fn new(key: RecordKeyType<'a>, value: Type<'a>) -> Self {
248		Self {
249			record: Record,
250			generics: Generics::new((Box::new(key), Comma, Box::new(value))),
251		}
252	}
253}
254
255/// Extension methods for `RecordKeyType`
256pub trait ExtendRecordKeyType<'a> {
257	fn byte() -> Self;
258	fn dom() -> Self;
259	fn usv() -> Self;
260	fn non_any(nat: NonAnyType<'a>) -> Self;
261}
262
263impl<'a> ExtendRecordKeyType<'a> for RecordKeyType<'a> {
264	fn byte() -> Self {
265		Self::Byte(ByteString)
266	}
267
268	fn dom() -> Self {
269		Self::DOM(DOMString)
270	}
271
272	fn usv() -> Self {
273		Self::USV(USVString)
274	}
275
276	fn non_any(nat: NonAnyType<'a>) -> Self {
277		Self::NonAny(nat)
278	}
279}
280
281/// Extension methods for `Type`
282pub trait ExtendType {
283	fn single_any() -> Self;
284}
285
286impl<'a> ExtendType for Type<'a> {
287	fn single_any() -> Self {
288		Self::Single(SingleType::any())
289	}
290}
291
292/// Extension methods for `SingleType`
293pub trait ExtendSingleType {
294	fn any() -> Self;
295}
296
297impl<'a> ExtendSingleType for SingleType<'a> {
298	fn any() -> Self {
299		Self::Any(Any)
300	}
301}
302
303#[cfg(test)]
304mod extend_maybenull {
305	use crate::extend::ExtendMayBeNull;
306	use weedle::term::{Boolean, Byte, QMark};
307	use weedle::types::MayBeNull;
308
309	#[test]
310	fn test_new() {
311		let maybe = MayBeNull::new(Byte, Some(QMark));
312		assert_eq!(maybe.type_, Byte);
313		assert_eq!(maybe.q_mark, Some(QMark));
314	}
315
316	#[test]
317	fn test_is_required() {
318		let maybe = MayBeNull::new_required(Boolean);
319		assert!(maybe.is_required());
320		assert!(maybe.q_mark.is_none());
321	}
322}
323
324#[cfg(test)]
325mod extend_float {
326	use crate::extend::{ExtendFloatingPointType, ExtendFloatingPointTypeNew};
327	use weedle::term::Unrestricted;
328	use weedle::types::{DoubleType, FloatType, FloatingPointType};
329
330	#[test]
331	fn test_unrestricted_webidl_f32() {
332		let wi_f32 = FloatingPointType::Float(FloatType::new_unrestricted());
333		assert_eq!(wi_f32.unrestricted(), Some(Unrestricted));
334	}
335
336	#[test]
337	fn test_unrestricted_webidl_f64() {
338		let wi_f64 = FloatingPointType::Double(DoubleType::new_unrestricted());
339		assert_eq!(wi_f64.unrestricted(), Some(Unrestricted));
340	}
341}
342
343#[cfg(test)]
344mod extend_integer {
345	use crate::extend::{ExtendIntegerType, ExtendIntegerTypeNew};
346	use weedle::term::Unsigned;
347	use weedle::types::{IntegerType, LongLongType, LongType, ShortType};
348
349	#[test]
350	fn test_short() {
351		let int1 = IntegerType::Short(ShortType::new_unsigned());
352		assert_eq!(int1.unsigned(), Some(Unsigned));
353
354		let int2 = IntegerType::Short(ShortType::new_signed());
355		assert_eq!(int2.unsigned(), None);
356	}
357
358	#[test]
359	fn test_long() {
360		let int1 = IntegerType::Long(LongType::new_unsigned());
361		assert_eq!(int1.unsigned(), Some(Unsigned));
362
363		let int2 = IntegerType::Long(LongType::new_signed());
364		assert_eq!(int2.unsigned(), None);
365	}
366
367	#[test]
368	fn test_long_long() {
369		let int1 = IntegerType::LongLong(LongLongType::new_unsigned());
370		assert_eq!(int1.unsigned(), Some(Unsigned));
371
372		let int2 = IntegerType::LongLong(LongLongType::new_signed());
373		assert_eq!(int2.unsigned(), None);
374	}
375}
376
377#[cfg(test)]
378mod extend_promise {
379	use crate::extend::{ExtendGenerics, ExtendNonAnyType, ExtendPromiseType};
380	use weedle::common::Generics;
381	use weedle::term::Promise;
382	use weedle::types::{NonAnyType, PromiseType, ReturnType, SingleType, Type};
383
384	#[test]
385	fn test_new() {
386		let p = PromiseType::new(ReturnType::Type(Type::Single(SingleType::NonAny(
387			NonAnyType::boolean(),
388		))));
389
390		assert_eq!(p.promise, Promise);
391		assert_eq!(
392			p.generics,
393			Generics::new(Box::new(ReturnType::Type(Type::Single(
394				SingleType::NonAny(NonAnyType::boolean())
395			))))
396		);
397	}
398}
399
400#[cfg(test)]
401mod extend_frozen_array {
402	use crate::extend::{ExtendFrozenArrayType, ExtendGenerics, ExtendNonAnyType};
403	use weedle::common::Generics;
404	use weedle::term::FrozenArray;
405	use weedle::types::{FrozenArrayType, NonAnyType, SingleType, Type};
406
407	#[test]
408	fn test_new() {
409		let f = FrozenArrayType::new(Type::Single(SingleType::NonAny(NonAnyType::boolean())));
410
411		assert_eq!(f.frozen_array, FrozenArray);
412		assert_eq!(
413			f.generics,
414			Generics::new(Box::new(Type::Single(SingleType::NonAny(
415				NonAnyType::boolean()
416			))))
417		);
418	}
419}
420
421#[cfg(test)]
422mod extend_record {
423	use crate::extend::{ExtendRecordKeyType, ExtendRecordType, ExtendType};
424	use weedle::types::{RecordKeyType, RecordType, Type};
425
426	#[test]
427	fn test_new() {
428		let r = RecordType::new(RecordKeyType::byte(), Type::single_any());
429
430		assert_eq!(*(r.generics.body.0), RecordKeyType::byte());
431		assert_eq!(*(r.generics.body.2), Type::single_any());
432	}
433}
434
435#[cfg(test)]
436mod extend_record_key {
437	use crate::extend::{ExtendNonAnyType, ExtendRecordKeyType};
438	use weedle::term::{Boolean, ByteString, DOMString, USVString};
439	use weedle::types::{MayBeNull, NonAnyType, RecordKeyType};
440
441	#[test]
442	fn test_variant_byte() {
443		assert_eq!(RecordKeyType::byte(), RecordKeyType::Byte(ByteString));
444	}
445
446	#[test]
447	fn test_variant_dom() {
448		assert_eq!(RecordKeyType::dom(), RecordKeyType::DOM(DOMString));
449	}
450
451	#[test]
452	fn test_variant_usv() {
453		assert_eq!(RecordKeyType::usv(), RecordKeyType::USV(USVString));
454	}
455
456	#[test]
457	fn test_variant_nat() {
458		assert_eq!(
459			RecordKeyType::non_any(NonAnyType::boolean()),
460			RecordKeyType::NonAny(NonAnyType::Boolean(MayBeNull {
461				type_: Boolean,
462				q_mark: None,
463			}))
464		);
465	}
466}