1use std::convert::TryInto;
2
3use super::*;
4use crate::{subr, call::IntoLispArgs};
5
6#[derive(Debug, Clone, Copy)]
29pub struct Vector<'e> {
30 value: Value<'e>,
31 len: usize,
32}
33
34impl<'e> Vector<'e> {
35 #[doc(hidden)]
36 #[inline]
37 pub fn from_value_unchecked(value: Value<'e>, len: usize) -> Self {
38 Self { value, len }
39 }
40
41 pub fn get<T: FromLisp<'e>>(&self, i: usize) -> Result<T> {
42 let v = self.value;
43 let env = v.env;
44 unsafe_raw_call_value_unprotected!(env, vec_get, v.raw, i as isize)?.into_rust()
49 }
50
51 pub fn set<T: IntoLisp<'e>>(&self, i: usize, value: T) -> Result<()> {
52 let v = self.value;
53 let env = v.env;
54 let value = value.into_lisp(env)?;
55 unsafe_raw_call!(env, vec_set, v.raw, i as isize, value.raw)
57 }
58
59 #[deprecated(since = "0.14.0", note = "Use .len() instead")]
60 #[doc(hidden)]
61 pub fn size(&self) -> Result<usize> {
62 Ok(self.len)
63 }
64
65 #[inline]
66 pub fn len(&self) -> usize {
67 self.len
68 }
69
70 #[inline]
71 pub fn value(&self) -> Value<'e> {
72 self.value
73 }
74}
75
76impl<'e> FromLisp<'e> for Vector<'e> {
77 fn from_lisp(value: Value<'e>) -> Result<Vector<'e>> {
78 let env = value.env;
79 let len = unsafe_raw_call!(env, vec_size, value.raw)?.try_into()
80 .expect("Invalid size from Emacs");
81 Ok(Vector { value, len })
82 }
83}
84
85impl<'e> IntoLisp<'e> for Vector<'e> {
86 #[inline(always)]
87 fn into_lisp(self, _: &'e Env) -> Result<Value<'_>> {
88 Ok(self.value)
89 }
90}
91
92pub struct IntoIter<'e> {
97 vector: Vector<'e>,
98 i: usize,
99}
100
101impl<'e> Iterator for IntoIter<'e> {
102 type Item = Value<'e>;
103
104 fn next(&mut self) -> Option<Self::Item> {
105 let i = self.i;
106 if i >= self.vector.len {
107 None
108 } else {
109 self.i += 1;
110 Some(self.vector.get(i).unwrap_or_else(|err| {
111 panic!("Unable to get Emacs vector's element at index {}: {}", i, err)
112 }))
113 }
114 }
115
116 fn size_hint(&self) -> (usize, Option<usize>) {
117 let remaining = self.vector.len - self.i;
118 (remaining, Some(remaining))
119 }
120}
121
122impl<'e> ExactSizeIterator for IntoIter<'e> {}
123
124impl<'e> IntoIterator for Vector<'e> {
125 type Item = Value<'e>;
126
127 type IntoIter = IntoIter<'e>;
128
129 #[inline]
130 fn into_iter(self) -> Self::IntoIter {
131 IntoIter { vector: self, i: 0 }
132 }
133}
134
135impl Env {
136 pub fn make_vector<'e, T: IntoLisp<'e>>(&'e self, length: usize, init: T) -> Result<Vector> {
137 let value = self.call(subr::make_vector, (length, init))?;
138 Ok(Vector::from_value_unchecked(value, length))
139 }
140
141 pub fn vector<'e, A: IntoLispArgs<'e>>(&'e self, args: A) -> Result<Value> {
142 self.call(subr::vector, args)
143 }
144}