ergo_lib_c_core/
collections.rs1use std::convert::{TryFrom, TryInto};
4
5use bounded_vec::{BoundedVec, BoundedVecOutOfBounds, OptBoundedVecToVec};
6
7use crate::error::*;
8use crate::util::{const_ptr_as_ref, mut_ptr_as_mut};
9
10pub struct Collection<T>(pub Vec<T>);
11pub type CollectionPtr<T> = *mut Collection<T>;
12pub type ConstCollectionPtr<T> = *const Collection<T>;
13
14pub unsafe fn collection_new<T>(collection_out: *mut CollectionPtr<T>) -> Result<(), Error> {
15 let collection_out = mut_ptr_as_mut(collection_out, "collection_out")?;
16 *collection_out = Box::into_raw(Box::new(Collection(vec![])));
17 Ok(())
18}
19
20pub unsafe fn collection_delete<T>(collection: CollectionPtr<T>) {
21 if !collection.is_null() {
22 let boxed = Box::from_raw(collection);
23 std::mem::drop(boxed);
24 }
25}
26
27pub unsafe fn collection_len<T>(collection: ConstCollectionPtr<T>) -> Result<usize, Error> {
28 let collection = const_ptr_as_ref(collection, "collection")?;
29 Ok(collection.0.len())
30}
31
32pub unsafe fn collection_get<T: Clone>(
33 collection: ConstCollectionPtr<T>,
34 index: usize,
35 elem_out: *mut *mut T,
36) -> Result<bool, Error> {
37 let collection = const_ptr_as_ref(collection, "collection")?;
38 let elem_out = mut_ptr_as_mut(elem_out, "elem_out")?;
39 if let Some(elem) = collection.0.get(index) {
40 *elem_out = Box::into_raw(Box::new(elem.clone()));
41 return Ok(true);
42 }
43 Ok(false)
44}
45
46pub unsafe fn collection_add<T: Clone>(
47 collection_out: CollectionPtr<T>,
48 elem: *const T,
49) -> Result<(), Error> {
50 let collection_out = mut_ptr_as_mut(collection_out, "collection_out")?;
51 let elem = const_ptr_as_ref(elem, "elem")?;
52 collection_out.0.push(elem.clone());
53 Ok(())
54}
55
56impl<T, S: Into<T>> From<Vec<S>> for Collection<T> {
57 fn from(vec: Vec<S>) -> Self {
58 Collection(vec.into_iter().map(Into::into).collect())
59 }
60}
61
62impl<T, S: Into<T>> From<Collection<S>> for Vec<T> {
63 fn from(vec: Collection<S>) -> Self {
64 vec.0.into_iter().map(Into::into).collect()
65 }
66}
67
68impl<T, S: Into<T> + Clone> From<&Collection<S>> for Vec<T> {
69 fn from(vec: &Collection<S>) -> Self {
70 vec.0.clone().into_iter().map(Into::into).collect()
71 }
72}
73
74impl<T, S: Into<T>, const L: usize, const U: usize> From<BoundedVec<S, L, U>> for Collection<T> {
75 fn from(bvec: BoundedVec<S, L, U>) -> Self {
76 bvec.to_vec().into()
77 }
78}
79
80impl<T, S: Into<T>, const L: usize, const U: usize> From<Option<BoundedVec<S, L, U>>>
81 for Collection<T>
82{
83 fn from(maybe_bvec: Option<BoundedVec<S, L, U>>) -> Self {
84 maybe_bvec.to_vec().into()
85 }
86}
87
88impl<T, S: Into<T> + Clone, const L: usize, const U: usize> TryFrom<Collection<S>>
89 for Option<BoundedVec<T, L, U>>
90{
91 type Error = BoundedVecOutOfBounds;
92
93 fn try_from(tokens: Collection<S>) -> Result<Self, Self::Error> {
94 (&tokens).try_into()
95 }
96}
97
98impl<T, S: Into<T> + Clone, const L: usize, const U: usize> TryFrom<&Collection<S>>
99 for Option<BoundedVec<T, L, U>>
100{
101 type Error = BoundedVecOutOfBounds;
102
103 fn try_from(tokens: &Collection<S>) -> Result<Self, Self::Error> {
104 if tokens.0.is_empty() {
105 Ok(None)
106 } else {
107 Ok(Some(
108 tokens
109 .0
110 .clone()
111 .into_iter()
112 .map(Into::into)
113 .collect::<Vec<T>>()
114 .try_into()?,
115 ))
116 }
117 }
118}