cel_cxx_ffi/common/
types.rs

1use crate::absl::{Span, SpanElement, StringView};
2use crate::common::TypeKind;
3use crate::protobuf::{Arena, DescriptorPool};
4use crate::Rep;
5
6#[cxx::bridge]
7mod ffi {
8    #[namespace = "google::protobuf"]
9    unsafe extern "C++" {
10        include!(<google/protobuf/arena.h>);
11        type Arena = super::Arena;
12
13        include!(<google/protobuf/descriptor.h>);
14        type DescriptorPool = super::DescriptorPool;
15    }
16
17    #[namespace = "absl"]
18    unsafe extern "C++" {
19        include!(<absl/strings/string_view.h>);
20        type string_view<'a> = super::StringView<'a>;
21    }
22
23    #[namespace = "cel"]
24    unsafe extern "C++" {
25        include!(<base/kind.h>);
26        type TypeKind = super::TypeKind;
27
28        include!(<common/type.h>);
29        type Type<'a> = super::Type<'a>;
30        fn name<'a>(self: &Type<'a>) -> string_view<'a>;
31        fn kind(self: &Type) -> TypeKind;
32
33        #[rust_name = "is_any"]
34        fn IsAny(self: &Type) -> bool;
35        #[rust_name = "is_bool"]
36        fn IsBool(self: &Type) -> bool;
37        #[rust_name = "is_bool_wrapper"]
38        fn IsBoolWrapper(self: &Type) -> bool;
39        #[rust_name = "is_bytes"]
40        fn IsBytes(self: &Type) -> bool;
41        #[rust_name = "is_bytes_wrapper"]
42        fn IsBytesWrapper(self: &Type) -> bool;
43        #[rust_name = "is_double"]
44        fn IsDouble(self: &Type) -> bool;
45        #[rust_name = "is_double_wrapper"]
46        fn IsDoubleWrapper(self: &Type) -> bool;
47        #[rust_name = "is_duration"]
48        fn IsDuration(self: &Type) -> bool;
49        #[rust_name = "is_dyn"]
50        fn IsDyn(self: &Type) -> bool;
51        #[rust_name = "is_enum"]
52        fn IsEnum(self: &Type) -> bool;
53        #[rust_name = "is_error"]
54        fn IsError(self: &Type) -> bool;
55        #[rust_name = "is_function"]
56        fn IsFunction(self: &Type) -> bool;
57        #[rust_name = "is_int"]
58        fn IsInt(self: &Type) -> bool;
59        #[rust_name = "is_int_wrapper"]
60        fn IsIntWrapper(self: &Type) -> bool;
61        #[rust_name = "is_list"]
62        fn IsList(self: &Type) -> bool;
63        #[rust_name = "is_map"]
64        fn IsMap(self: &Type) -> bool;
65        #[rust_name = "is_message"]
66        fn IsMessage(self: &Type) -> bool;
67        #[rust_name = "is_null"]
68        fn IsNull(self: &Type) -> bool;
69        #[rust_name = "is_opaque"]
70        fn IsOpaque(self: &Type) -> bool;
71        #[rust_name = "is_optional"]
72        fn IsOptional(self: &Type) -> bool;
73        #[rust_name = "is_string"]
74        fn IsString(self: &Type) -> bool;
75        #[rust_name = "is_string_wrapper"]
76        fn IsStringWrapper(self: &Type) -> bool;
77        #[rust_name = "is_struct"]
78        fn IsStruct(self: &Type) -> bool;
79        #[rust_name = "is_timestamp"]
80        fn IsTimestamp(self: &Type) -> bool;
81        #[rust_name = "is_type_param"]
82        fn IsTypeParam(self: &Type) -> bool;
83        #[rust_name = "is_type"]
84        fn IsType(self: &Type) -> bool;
85        #[rust_name = "is_uint"]
86        fn IsUint(self: &Type) -> bool;
87        #[rust_name = "is_uint_wrapper"]
88        fn IsUintWrapper(self: &Type) -> bool;
89        #[rust_name = "is_unknown"]
90        fn IsUnknown(self: &Type) -> bool;
91
92        #[rust_name = "get_enum"]
93        fn GetEnum<'a>(self: &Type<'a>) -> EnumType<'a>;
94        #[rust_name = "get_function"]
95        fn GetFunction<'a>(self: &Type<'a>) -> FunctionType<'a>;
96        #[rust_name = "get_list"]
97        fn GetList<'a>(self: &Type<'a>) -> ListType<'a>;
98        #[rust_name = "get_map"]
99        fn GetMap<'a>(self: &Type<'a>) -> MapType<'a>;
100        #[rust_name = "get_message"]
101        fn GetMessage<'a>(self: &Type<'a>) -> MessageType<'a>;
102        #[rust_name = "get_opaque"]
103        fn GetOpaque<'a>(self: &Type<'a>) -> OpaqueType<'a>;
104        #[rust_name = "get_optional"]
105        fn GetOptional<'a>(self: &Type<'a>) -> OptionalType<'a>;
106        #[rust_name = "get_struct"]
107        fn GetStruct<'a>(self: &Type<'a>) -> StructType<'a>;
108        #[rust_name = "get_type_param"]
109        fn GetTypeParam<'a>(self: &Type<'a>) -> TypeParamType<'a>;
110        #[rust_name = "get_type"]
111        fn GetType<'a>(self: &Type<'a>) -> TypeType<'a>;
112
113        type EnumType<'a> = super::EnumType<'a>;
114        fn name<'a>(self: &EnumType<'a>) -> string_view<'a>;
115
116        type FunctionType<'a> = super::FunctionType<'a>;
117        #[rust_name = "arguments"]
118        fn args<'a>(self: &FunctionType<'a>) -> Span_Type<'a, 'a>;
119        fn result<'a>(self: &FunctionType<'a>) -> &'a Type<'a>;
120
121        type ListType<'a> = super::ListType<'a>;
122        #[rust_name = "element"]
123        fn GetElement<'a>(self: &ListType<'a>) -> Type<'a>;
124        type MapType<'a> = super::MapType<'a>;
125        #[rust_name = "key"]
126        fn GetKey<'a>(self: &MapType<'a>) -> Type<'a>;
127        #[rust_name = "value"]
128        fn GetValue<'a>(self: &MapType<'a>) -> Type<'a>;
129
130        type MessageType<'a> = super::MessageType<'a>;
131        fn name<'a>(self: &MessageType<'a>) -> string_view<'a>;
132
133        type OpaqueType<'a> = super::OpaqueType<'a>;
134        fn name<'a>(self: &OpaqueType<'a>) -> string_view<'a>;
135        #[rust_name = "parameters"]
136        fn GetParameters<'a>(self: &OpaqueType<'a>) -> TypeParameters<'a>;
137        #[rust_name = "is_optional"]
138        fn IsOptional(self: &OpaqueType) -> bool;
139        #[rust_name = "as_optional"]
140        fn GetOptional<'a>(self: &OpaqueType<'a>) -> OptionalType<'a>;
141
142        type OptionalType<'a> = super::OptionalType<'a>;
143        #[rust_name = "parameter"]
144        fn GetParameter<'a>(self: &OptionalType<'a>) -> Type<'a>;
145
146        type StructType<'a> = super::StructType<'a>;
147        fn name<'a>(self: &StructType<'a>) -> string_view<'a>;
148        #[rust_name = "get_parameters"]
149        fn GetParameters<'a>(self: &StructType<'a>) -> TypeParameters<'a>;
150        #[rust_name = "is_message"]
151        fn IsMessage(self: &StructType) -> bool;
152        #[rust_name = "get_message"]
153        fn GetMessage<'a>(self: &StructType<'a>) -> MessageType<'a>;
154
155        type TypeParamType<'a> = super::TypeParamType<'a>;
156        fn name<'a>(self: &TypeParamType<'a>) -> string_view<'a>;
157
158        type TypeType<'a> = super::TypeType<'a>;
159        #[rust_name = "get_type"]
160        fn GetType<'a>(self: &TypeType<'a>) -> Type<'a>;
161
162        type TypeParameters<'a> = super::TypeParameters<'a>;
163        #[rust_name = "len"]
164        fn size(self: &TypeParameters) -> usize;
165        #[rust_name = "is_empty"]
166        fn empty(self: &TypeParameters) -> bool;
167    }
168
169    #[namespace = "rust::cel_cxx"]
170    unsafe extern "C++" {
171        include!(<cel-cxx-ffi/include/types.h>);
172        type Span_Type<'s, 'a> = super::Span<'s, Type<'a>>;
173
174        fn Type_new_any() -> Type<'static>;
175        fn Type_new_bool() -> Type<'static>;
176        fn Type_new_bool_wrapper() -> Type<'static>;
177        fn Type_new_bytes() -> Type<'static>;
178        fn Type_new_bytes_wrapper() -> Type<'static>;
179        fn Type_new_double() -> Type<'static>;
180        fn Type_new_double_wrapper() -> Type<'static>;
181        fn Type_new_duration() -> Type<'static>;
182        fn Type_new_dyn() -> Type<'static>;
183        fn Type_new_enum<'a>(enum_type: &EnumType<'a>) -> Type<'a>;
184        fn Type_new_error() -> Type<'static>;
185        fn Type_new_function<'a>(function_type: &FunctionType<'a>) -> Type<'static>;
186        fn Type_new_int() -> Type<'static>;
187        fn Type_new_int_wrapper() -> Type<'static>;
188        fn Type_new_list<'a>(list_type: &ListType<'a>) -> Type<'a>;
189        fn Type_new_map<'a>(map_type: &MapType<'a>) -> Type<'a>;
190        fn Type_new_message<'a>(message_type: &MessageType<'a>) -> Type<'a>;
191        fn Type_new_null() -> Type<'static>;
192        fn Type_new_opaque<'a>(opaque_type: &OpaqueType<'a>) -> Type<'a>;
193        fn Type_new_optional<'a>(optional_type: &OptionalType<'a>) -> Type<'a>;
194        fn Type_new_string() -> Type<'static>;
195        fn Type_new_string_wrapper() -> Type<'static>;
196        fn Type_new_struct<'a>(struct_type: &StructType<'a>) -> Type<'a>;
197        fn Type_new_timestamp() -> Type<'static>;
198        fn Type_new_type_param<'a>(type_param_type: &TypeParamType<'a>) -> Type<'a>;
199        fn Type_new_type<'a>(type_type: &TypeType<'a>) -> Type<'a>;
200        fn Type_new_uint() -> Type<'static>;
201        fn Type_new_uint_wrapper() -> Type<'static>;
202        fn Type_new_unknown() -> Type<'static>;
203
204        // EnumType
205        fn EnumType_new<'a>(descriptor_pool: &'a DescriptorPool, name: &str) -> EnumType<'a>;
206
207        // FunctionType
208        fn FunctionType_new<'a>(
209            arena: &'a Arena,
210            result: &Type<'a>,
211            arguments: &[Type<'a>],
212        ) -> FunctionType<'a>;
213
214        // ListType
215        fn ListType_new<'a>(arena: &'a Arena, element: &Type<'a>) -> ListType<'a>;
216
217        // MapType
218        fn MapType_new<'a>(arena: &'a Arena, key: &Type<'a>, value: &Type<'a>) -> MapType<'a>;
219
220        // MessageType
221        fn MessageType_new<'a>(pool: &'a DescriptorPool, name: &str) -> MessageType<'a>;
222
223        // OpaqueType
224        fn OpaqueType_new<'a>(
225            arena: &'a Arena,
226            name: &str,
227            parameters: &[Type<'a>],
228        ) -> OpaqueType<'a>;
229
230        // OptionalType
231        fn OptionalType_default() -> OptionalType<'static>;
232        fn OptionalType_new<'a>(arena: &'a Arena, parameter: &Type<'a>) -> OptionalType<'a>;
233
234        // StructType
235        fn StructType_default() -> StructType<'static>;
236        fn StructType_new_message<'a>(message_type: &MessageType<'a>) -> StructType<'a>;
237        fn StructType_new_basic<'a>(name: &'a str) -> StructType<'a>;
238
239        // TypeParamType
240        fn TypeParamType_default() -> TypeParamType<'static>;
241        fn TypeParamType_new<'a>(name: &str, arena: &'a Arena) -> TypeParamType<'a>;
242
243        // TypeType
244        fn TypeType_default() -> TypeType<'static>;
245        fn TypeType_new<'a>(arena: &'a Arena, parameter: &Type<'a>) -> TypeType<'a>;
246        fn TypeType_has_type(type_type: &TypeType) -> bool;
247
248        // TypeParameters
249        unsafe fn TypeParameters_get_unchecked<'a>(
250            type_parameters: &TypeParameters<'a>,
251            index: usize,
252        ) -> &'a Type<'a>;
253    }
254}
255
256// cel::Type is a variant of all subtypes.
257// The largest type is BasicStructType, TypeParamType which contains a
258// std::string_view.
259//
260// So we use 2 pointers size to store the type.
261#[repr(transparent)]
262#[derive(Copy, Clone)]
263pub struct Type<'a>(Rep<'a, usize, 3>);
264
265unsafe impl<'a> cxx::ExternType for Type<'a> {
266    type Id = cxx::type_id!("cel::Type");
267    type Kind = cxx::kind::Trivial;
268}
269
270impl<'a> crate::SizedExternType for Type<'a> {}
271
272impl<'a> SpanElement for Type<'a> {
273    type TypeId = cxx::type_id!("rust::cel_cxx::Span_Type");
274}
275
276impl<'a> Type<'a> {
277    pub fn new_any() -> Self {
278        ffi::Type_new_any()
279    }
280    pub fn new_bool() -> Self {
281        ffi::Type_new_bool()
282    }
283    pub fn new_bool_wrapper() -> Self {
284        ffi::Type_new_bool_wrapper()
285    }
286    pub fn new_bytes() -> Self {
287        ffi::Type_new_bytes()
288    }
289    pub fn new_bytes_wrapper() -> Self {
290        ffi::Type_new_bytes_wrapper()
291    }
292    pub fn new_double() -> Self {
293        ffi::Type_new_double()
294    }
295    pub fn new_double_wrapper() -> Self {
296        ffi::Type_new_double_wrapper()
297    }
298    pub fn new_duration() -> Self {
299        ffi::Type_new_duration()
300    }
301    pub fn new_dyn() -> Self {
302        ffi::Type_new_dyn()
303    }
304    pub fn new_enum(enum_type: &EnumType<'a>) -> Self {
305        ffi::Type_new_enum(enum_type)
306    }
307    pub fn new_error() -> Self {
308        ffi::Type_new_error()
309    }
310    pub fn new_function(function_type: &FunctionType<'a>) -> Self {
311        ffi::Type_new_function(function_type)
312    }
313    pub fn new_int() -> Self {
314        ffi::Type_new_int()
315    }
316    pub fn new_int_wrapper() -> Self {
317        ffi::Type_new_int_wrapper()
318    }
319    pub fn new_list(list_type: &ListType<'a>) -> Self {
320        ffi::Type_new_list(list_type)
321    }
322    pub fn new_map(map_type: &MapType<'a>) -> Self {
323        ffi::Type_new_map(map_type)
324    }
325    pub fn new_message(message_type: &MessageType<'a>) -> Self {
326        ffi::Type_new_message(message_type)
327    }
328    pub fn new_null() -> Self {
329        ffi::Type_new_null()
330    }
331    pub fn new_opaque(opaque_type: &OpaqueType<'a>) -> Self {
332        ffi::Type_new_opaque(opaque_type)
333    }
334    pub fn new_optional(optional_type: &OptionalType<'a>) -> Self {
335        ffi::Type_new_optional(optional_type)
336    }
337    pub fn new_string() -> Self {
338        ffi::Type_new_string()
339    }
340    pub fn new_string_wrapper() -> Self {
341        ffi::Type_new_string_wrapper()
342    }
343    pub fn new_struct(struct_type: &StructType<'a>) -> Self {
344        ffi::Type_new_struct(struct_type)
345    }
346    pub fn new_timestamp() -> Self {
347        ffi::Type_new_timestamp()
348    }
349    pub fn new_type_param(type_param_type: &TypeParamType<'a>) -> Self {
350        ffi::Type_new_type_param(type_param_type)
351    }
352    pub fn new_type(type_type: &TypeType<'a>) -> Self {
353        ffi::Type_new_type(type_type)
354    }
355    pub fn new_uint() -> Self {
356        ffi::Type_new_uint()
357    }
358    pub fn new_uint_wrapper() -> Self {
359        ffi::Type_new_uint_wrapper()
360    }
361    pub fn new_unknown() -> Self {
362        ffi::Type_new_unknown()
363    }
364}
365
366// EnumType stores a pointer to the descriptor.
367//
368// So we use 1 pointer size to store the type.
369#[repr(transparent)]
370#[derive(Copy, Clone)]
371pub struct EnumType<'a>(Rep<'a, usize, 1>);
372
373unsafe impl<'a> cxx::ExternType for EnumType<'a> {
374    type Id = cxx::type_id!("cel::EnumType");
375    type Kind = cxx::kind::Trivial;
376}
377
378impl<'a> EnumType<'a> {
379    pub fn new(descriptor_pool: &'a DescriptorPool, name: &str) -> Self {
380        ffi::EnumType_new(descriptor_pool, name)
381    }
382}
383
384// FunctionType stores a pointer.
385//
386// So we use 1 pointer size to store the type.
387#[repr(transparent)]
388#[derive(Copy, Clone)]
389pub struct FunctionType<'a>(Rep<'a, usize, 1>);
390
391unsafe impl<'a> cxx::ExternType for FunctionType<'a> {
392    type Id = cxx::type_id!("cel::FunctionType");
393    type Kind = cxx::kind::Trivial;
394}
395
396impl<'a> FunctionType<'a> {
397    pub fn new(arena: &'a Arena, result: &Type<'a>, arguments: &[Type<'a>]) -> Self {
398        ffi::FunctionType_new(arena, result, arguments)
399    }
400}
401
402// ListType stores a `uintptr_t`.
403//
404// So we use 1 pointer size to store the type.
405#[repr(transparent)]
406#[derive(Copy, Clone)]
407pub struct ListType<'a>(Rep<'a, usize, 1>);
408
409unsafe impl<'a> cxx::ExternType for ListType<'a> {
410    type Id = cxx::type_id!("cel::ListType");
411    type Kind = cxx::kind::Trivial;
412}
413
414impl<'a> ListType<'a> {
415    pub fn new(arena: &'a Arena, element: &Type<'a>) -> Self {
416        ffi::ListType_new(arena, element)
417    }
418}
419
420// MapType stores a `uintptr_t`.
421//
422// So we use 1 pointer size to store the type.
423#[repr(transparent)]
424#[derive(Copy, Clone)]
425pub struct MapType<'a>(Rep<'a, usize, 1>);
426
427unsafe impl<'a> cxx::ExternType for MapType<'a> {
428    type Id = cxx::type_id!("cel::MapType");
429    type Kind = cxx::kind::Trivial;
430}
431
432impl<'a> MapType<'a> {
433    pub fn new(arena: &'a Arena, key: &Type<'a>, value: &Type<'a>) -> Self {
434        ffi::MapType_new(arena, key, value)
435    }
436}
437
438// MessageType stores a pointer to the descriptor.
439//
440// So we use 1 pointer size to store the type.
441#[repr(transparent)]
442#[derive(Copy, Clone)]
443pub struct MessageType<'a>(Rep<'a, usize, 1>);
444
445unsafe impl<'a> cxx::ExternType for MessageType<'a> {
446    type Id = cxx::type_id!("cel::MessageType");
447    type Kind = cxx::kind::Trivial;
448}
449
450impl<'a> MessageType<'a> {
451    pub fn new(pool: &'a DescriptorPool, name: &str) -> Self {
452        ffi::MessageType_new(pool, name)
453    }
454}
455
456// OpaqueType stores a pointer to the data.
457//
458// So we use 1 pointer size to store the type.
459#[repr(transparent)]
460#[derive(Copy, Clone)]
461pub struct OpaqueType<'a>(Rep<'a, usize, 1>);
462
463unsafe impl<'a> cxx::ExternType for OpaqueType<'a> {
464    type Id = cxx::type_id!("cel::OpaqueType");
465    type Kind = cxx::kind::Trivial;
466}
467
468impl<'a> OpaqueType<'a> {
469    pub fn new(arena: &'a Arena, name: &str, parameters: &[Type<'a>]) -> Self {
470        ffi::OpaqueType_new(arena, name, parameters)
471    }
472}
473
474// OptionalType is a wrapper on OpaqueType.
475//
476// So we use 1 pointer size to store the type.
477#[repr(transparent)]
478#[derive(Copy, Clone)]
479pub struct OptionalType<'a>(Rep<'a, usize, 1>);
480
481unsafe impl<'a> cxx::ExternType for OptionalType<'a> {
482    type Id = cxx::type_id!("cel::OptionalType");
483    type Kind = cxx::kind::Trivial;
484}
485
486impl Default for OptionalType<'static> {
487    fn default() -> Self {
488        ffi::OptionalType_default()
489    }
490}
491
492impl<'a> OptionalType<'a> {
493    pub fn new(arena: &'a Arena, parameter: &Type<'a>) -> Self {
494        ffi::OptionalType_new(arena, parameter)
495    }
496}
497
498// StructType contains a StructTypeVariant, which largest member is
499// BasicStructType contains a std::string_view.
500//
501// So we use 2 pointers size to store the type.
502#[repr(transparent)]
503#[derive(Copy, Clone)]
504pub struct StructType<'a>(Rep<'a, usize, 2>);
505
506unsafe impl<'a> cxx::ExternType for StructType<'a> {
507    type Id = cxx::type_id!("cel::StructType");
508    type Kind = cxx::kind::Trivial;
509}
510
511impl Default for StructType<'static> {
512    fn default() -> Self {
513        ffi::StructType_default()
514    }
515}
516
517impl<'a> StructType<'a> {
518    pub fn new_message(message_type: &MessageType<'a>) -> Self {
519        ffi::StructType_new_message(message_type)
520    }
521    pub fn new_basic(name: &'a str) -> Self {
522        ffi::StructType_new_basic(name)
523    }
524}
525
526// TypeParamType stores a std::string_view.
527//
528// So we use 1 pointer size to store the type.
529#[repr(transparent)]
530#[derive(Copy, Clone)]
531pub struct TypeParamType<'a>(Rep<'a, usize, 1>);
532
533unsafe impl<'a> cxx::ExternType for TypeParamType<'a> {
534    type Id = cxx::type_id!("cel::TypeParamType");
535    type Kind = cxx::kind::Trivial;
536}
537
538impl Default for TypeParamType<'static> {
539    fn default() -> Self {
540        ffi::TypeParamType_default()
541    }
542}
543
544impl<'a> TypeParamType<'a> {
545    pub fn new(name: &str, arena: &'a Arena) -> Self {
546        ffi::TypeParamType_new(name, arena)
547    }
548}
549
550// TypeType stores a pointer to the data.
551//
552// So we use 1 pointer size to store the type.
553#[repr(transparent)]
554#[derive(Copy, Clone)]
555pub struct TypeType<'a>(Rep<'a, usize, 1>);
556
557unsafe impl<'a> cxx::ExternType for TypeType<'a> {
558    type Id = cxx::type_id!("cel::TypeType");
559    type Kind = cxx::kind::Trivial;
560}
561
562impl Default for TypeType<'static> {
563    fn default() -> Self {
564        ffi::TypeType_default()
565    }
566}
567
568impl<'a> TypeType<'a> {
569    pub fn new(arena: &'a Arena, parameter: &Type<'a>) -> Self {
570        ffi::TypeType_new(arena, parameter)
571    }
572    pub fn has_type(&self) -> bool {
573        ffi::TypeType_has_type(self)
574    }
575}
576
577// TypeParameters stores a size_t and a array of two `Type`s.
578//
579// So we use 5 pointers size to store the type.
580#[repr(transparent)]
581#[derive(Copy, Clone)]
582pub struct TypeParameters<'a>(Rep<'a, usize, 5>);
583
584unsafe impl<'a> cxx::ExternType for TypeParameters<'a> {
585    type Id = cxx::type_id!("cel::TypeParameters");
586    type Kind = cxx::kind::Trivial;
587}
588
589impl<'a> TypeParameters<'a> {
590    pub fn iter(&self) -> TypeParametersIter<'a> {
591        TypeParametersIter {
592            type_parameters: *self,
593            index: 0,
594        }
595    }
596
597    pub fn get(&self, index: usize) -> Option<&Type<'a>> {
598        if index < self.len() {
599            Some(unsafe { self.get_unchecked(index) })
600        } else {
601            None
602        }
603    }
604
605    /// Get a type parameter at the specified index without bounds checking.
606    ///
607    /// # Safety
608    ///
609    /// The caller must ensure that `index` is less than `self.len()`.
610    /// Calling this method with an out-of-bounds index is undefined behavior.
611    pub unsafe fn get_unchecked(&self, index: usize) -> &Type<'a> {
612        unsafe { ffi::TypeParameters_get_unchecked(self, index) }
613    }
614}
615
616impl<'a> std::iter::IntoIterator for TypeParameters<'a> {
617    type Item = Type<'a>;
618    type IntoIter = TypeParametersIter<'a>;
619
620    fn into_iter(self) -> Self::IntoIter {
621        self.iter()
622    }
623}
624
625impl<'a> std::ops::Index<usize> for TypeParameters<'a> {
626    type Output = Type<'a>;
627
628    fn index(&self, index: usize) -> &Self::Output {
629        unsafe { self.get_unchecked(index) }
630    }
631}
632
633pub struct TypeParametersIter<'a> {
634    type_parameters: TypeParameters<'a>,
635    index: usize,
636}
637
638impl<'a> std::iter::Iterator for TypeParametersIter<'a> {
639    type Item = Type<'a>;
640
641    fn next(&mut self) -> Option<Self::Item> {
642        if self.index < self.type_parameters.len() {
643            let item = self.type_parameters[self.index];
644            self.index += 1;
645            Some(item)
646        } else {
647            None
648        }
649    }
650
651    fn size_hint(&self) -> (usize, Option<usize>) {
652        (
653            self.type_parameters.len() - self.index,
654            Some(self.type_parameters.len() - self.index),
655        )
656    }
657}
658
659impl<'a> std::iter::ExactSizeIterator for TypeParametersIter<'a> {
660    fn len(&self) -> usize {
661        self.type_parameters.len() - self.index
662    }
663}
664
665impl<'a> std::iter::FusedIterator for TypeParametersIter<'a> {}