2 use foreign_types
::{ForeignType, ForeignTypeRef, Opaque}
;
4 use std
::borrow
::Borrow
;
5 use std
::convert
::AsRef
;
8 use std
::marker
::PhantomData
;
10 use std
::ops
::{Deref, DerefMut, Index, IndexMut, Range}
;
12 use crate::error
::ErrorStack
;
13 use crate::util
::ForeignTypeExt
;
14 use crate::{cvt, cvt_p}
;
19 OPENSSL_sk_pop
, OPENSSL_sk_free
, OPENSSL_sk_num
, OPENSSL_sk_value
, OPENSSL_STACK
,
20 OPENSSL_sk_new_null
, OPENSSL_sk_push
,
24 sk_pop
as OPENSSL_sk_pop
, sk_free
as OPENSSL_sk_free
, sk_num
as OPENSSL_sk_num
,
25 sk_value
as OPENSSL_sk_value
, _STACK
as OPENSSL_STACK
,
26 sk_new_null
as OPENSSL_sk_new_null
, sk_push
as OPENSSL_sk_push
,
31 /// Trait implemented by types which can be placed in a stack.
33 /// It should not be implemented for any type outside of this crate.
34 pub trait Stackable
: ForeignType
{
35 /// The C stack type for this element.
37 /// Generally called `stack_st_{ELEMENT_TYPE}`, normally hidden by the
38 /// `STACK_OF(ELEMENT_TYPE)` macro in the OpenSSL API.
42 /// An owned stack of `T`.
43 pub struct Stack
<T
: Stackable
>(*mut T
::StackType
);
45 unsafe impl<T
: Stackable
+ Send
> Send
for Stack
<T
> {}
46 unsafe impl<T
: Stackable
+ Sync
> Sync
for Stack
<T
> {}
48 impl<T
> fmt
::Debug
for Stack
<T
>
53 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
54 fmt
.debug_list().entries(self).finish()
57 impl<T
: Stackable
> Drop
for Stack
<T
> {
60 while self.pop().is_some() {}
61 OPENSSL_sk_free(self.0 as *mut _
);
66 impl<T
: Stackable
> Stack
<T
> {
67 pub fn new() -> Result
<Stack
<T
>, ErrorStack
> {
70 let ptr
= cvt_p(OPENSSL_sk_new_null())?
;
71 Ok(Stack(ptr
as *mut _
))
76 impl<T
: Stackable
> iter
::IntoIterator
for Stack
<T
> {
77 type IntoIter
= IntoIter
<T
>;
80 fn into_iter(self) -> IntoIter
<T
> {
83 idxs
: 0..self.len() as c_int
,
90 impl<T
: Stackable
> AsRef
<StackRef
<T
>> for Stack
<T
> {
91 fn as_ref(&self) -> &StackRef
<T
> {
96 impl<T
: Stackable
> Borrow
<StackRef
<T
>> for Stack
<T
> {
97 fn borrow(&self) -> &StackRef
<T
> {
102 impl<T
: Stackable
> ForeignType
for Stack
<T
> {
103 type CType
= T
::StackType
;
104 type Ref
= StackRef
<T
>;
107 unsafe fn from_ptr(ptr
: *mut T
::StackType
) -> Stack
<T
> {
110 "Must not instantiate a Stack from a null-ptr - use Stack::new() in \
117 fn as_ptr(&self) -> *mut T
::StackType
{
122 impl<T
: Stackable
> Deref
for Stack
<T
> {
123 type Target
= StackRef
<T
>;
125 fn deref(&self) -> &StackRef
<T
> {
126 unsafe { StackRef::from_ptr(self.0) }
130 impl<T
: Stackable
> DerefMut
for Stack
<T
> {
131 fn deref_mut(&mut self) -> &mut StackRef
<T
> {
132 unsafe { StackRef::from_ptr_mut(self.0) }
136 pub struct IntoIter
<T
: Stackable
> {
137 stack
: *mut T
::StackType
,
141 impl<T
: Stackable
> Drop
for IntoIter
<T
> {
144 while let Some(_
) = self.next() {}
145 OPENSSL_sk_free(self.stack
as *mut _
);
150 impl<T
: Stackable
> Iterator
for IntoIter
<T
> {
153 fn next(&mut self) -> Option
<T
> {
157 .map(|i
| T
::from_ptr(OPENSSL_sk_value(self.stack
as *mut _
, i
) as *mut _
))
161 fn size_hint(&self) -> (usize, Option
<usize>) {
162 self.idxs
.size_hint()
166 impl<T
: Stackable
> DoubleEndedIterator
for IntoIter
<T
> {
167 fn next_back(&mut self) -> Option
<T
> {
171 .map(|i
| T
::from_ptr(OPENSSL_sk_value(self.stack
as *mut _
, i
) as *mut _
))
176 impl<T
: Stackable
> ExactSizeIterator
for IntoIter
<T
> {}
178 pub struct StackRef
<T
: Stackable
>(Opaque
, PhantomData
<T
>);
180 unsafe impl<T
: Stackable
+ Send
> Send
for StackRef
<T
> {}
181 unsafe impl<T
: Stackable
+ Sync
> Sync
for StackRef
<T
> {}
183 impl<T
: Stackable
> ForeignTypeRef
for StackRef
<T
> {
184 type CType
= T
::StackType
;
187 impl<T
: Stackable
> StackRef
<T
> {
188 fn as_stack(&self) -> *mut OPENSSL_STACK
{
189 self.as_ptr() as *mut _
192 /// Returns the number of items in the stack.
193 pub fn len(&self) -> usize {
194 unsafe { OPENSSL_sk_num(self.as_stack()) as usize }
197 /// Determines if the stack is empty.
198 pub fn is_empty(&self) -> bool
{
202 pub fn iter(&self) -> Iter
<'_
, T
> {
205 idxs
: 0..self.len() as c_int
,
209 pub fn iter_mut(&mut self) -> IterMut
<'_
, T
> {
211 idxs
: 0..self.len() as c_int
,
216 /// Returns a reference to the element at the given index in the
217 /// stack or `None` if the index is out of bounds
218 pub fn get(&self, idx
: usize) -> Option
<&T
::Ref
> {
220 if idx
>= self.len() {
224 Some(T
::Ref
::from_ptr(self._get(idx
)))
228 /// Returns a mutable reference to the element at the given index in the
229 /// stack or `None` if the index is out of bounds
230 pub fn get_mut(&mut self, idx
: usize) -> Option
<&mut T
::Ref
> {
232 if idx
>= self.len() {
236 Some(T
::Ref
::from_ptr_mut(self._get(idx
)))
240 /// Pushes a value onto the top of the stack.
241 pub fn push(&mut self, data
: T
) -> Result
<(), ErrorStack
> {
243 cvt(OPENSSL_sk_push(self.as_stack(), data
.as_ptr() as *mut _
))?
;
249 /// Removes the last element from the stack and returns it.
250 pub fn pop(&mut self) -> Option
<T
> {
252 let ptr
= OPENSSL_sk_pop(self.as_stack());
253 T
::from_ptr_opt(ptr
as *mut _
)
257 unsafe fn _get(&self, idx
: usize) -> *mut T
::CType
{
258 OPENSSL_sk_value(self.as_stack(), idx
as c_int
) as *mut _
262 impl<T
: Stackable
> Index
<usize> for StackRef
<T
> {
263 type Output
= T
::Ref
;
265 fn index(&self, index
: usize) -> &T
::Ref
{
266 self.get(index
).unwrap()
270 impl<T
: Stackable
> IndexMut
<usize> for StackRef
<T
> {
271 fn index_mut(&mut self, index
: usize) -> &mut T
::Ref
{
272 self.get_mut(index
).unwrap()
276 impl<'a
, T
: Stackable
> iter
::IntoIterator
for &'a StackRef
<T
> {
277 type Item
= &'a T
::Ref
;
278 type IntoIter
= Iter
<'a
, T
>;
280 fn into_iter(self) -> Iter
<'a
, T
> {
285 impl<'a
, T
: Stackable
> iter
::IntoIterator
for &'a
mut StackRef
<T
> {
286 type Item
= &'a
mut T
::Ref
;
287 type IntoIter
= IterMut
<'a
, T
>;
289 fn into_iter(self) -> IterMut
<'a
, T
> {
294 impl<'a
, T
: Stackable
> iter
::IntoIterator
for &'a Stack
<T
> {
295 type Item
= &'a T
::Ref
;
296 type IntoIter
= Iter
<'a
, T
>;
298 fn into_iter(self) -> Iter
<'a
, T
> {
303 impl<'a
, T
: Stackable
> iter
::IntoIterator
for &'a
mut Stack
<T
> {
304 type Item
= &'a
mut T
::Ref
;
305 type IntoIter
= IterMut
<'a
, T
>;
307 fn into_iter(self) -> IterMut
<'a
, T
> {
312 /// An iterator over the stack's contents.
313 pub struct Iter
<'a
, T
: Stackable
> {
314 stack
: &'a StackRef
<T
>,
318 impl<'a
, T
: Stackable
> Iterator
for Iter
<'a
, T
> {
319 type Item
= &'a T
::Ref
;
321 fn next(&mut self) -> Option
<&'a T
::Ref
> {
325 .map(|i
| T
::Ref
::from_ptr(OPENSSL_sk_value(self.stack
.as_stack(), i
) as *mut _
))
329 fn size_hint(&self) -> (usize, Option
<usize>) {
330 self.idxs
.size_hint()
334 impl<'a
, T
: Stackable
> DoubleEndedIterator
for Iter
<'a
, T
> {
335 fn next_back(&mut self) -> Option
<&'a T
::Ref
> {
339 .map(|i
| T
::Ref
::from_ptr(OPENSSL_sk_value(self.stack
.as_stack(), i
) as *mut _
))
344 impl<'a
, T
: Stackable
> ExactSizeIterator
for Iter
<'a
, T
> {}
346 /// A mutable iterator over the stack's contents.
347 pub struct IterMut
<'a
, T
: Stackable
> {
348 stack
: &'a
mut StackRef
<T
>,
352 impl<'a
, T
: Stackable
> Iterator
for IterMut
<'a
, T
> {
353 type Item
= &'a
mut T
::Ref
;
355 fn next(&mut self) -> Option
<&'a
mut T
::Ref
> {
359 .map(|i
| T
::Ref
::from_ptr_mut(OPENSSL_sk_value(self.stack
.as_stack(), i
) as *mut _
))
363 fn size_hint(&self) -> (usize, Option
<usize>) {
364 self.idxs
.size_hint()
368 impl<'a
, T
: Stackable
> DoubleEndedIterator
for IterMut
<'a
, T
> {
369 fn next_back(&mut self) -> Option
<&'a
mut T
::Ref
> {
373 .map(|i
| T
::Ref
::from_ptr_mut(OPENSSL_sk_value(self.stack
.as_stack(), i
) as *mut _
))
378 impl<'a
, T
: Stackable
> ExactSizeIterator
for IterMut
<'a
, T
> {}