rune/runtime/
bytes.rs

1//! A container of bytes, corresponding to the [Value::Bytes] type.
2//!
3//! [Value::Bytes]: crate::Value::Bytes.
4
5use core::fmt;
6use core::ops;
7
8#[cfg(feature = "musli")]
9use musli::{Decode, Encode};
10#[cfg(feature = "serde")]
11use serde::de;
12#[cfg(feature = "serde")]
13use serde::ser;
14
15use crate as rune;
16use crate::alloc::prelude::*;
17use crate::alloc::{self, Box, Vec};
18use crate::TypeHash as _;
19use crate::{Any, FromValue};
20
21use super::{
22    Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, RawAnyGuard, Ref,
23    RuntimeError, UnsafeToRef, Value, VmError, VmErrorKind,
24};
25
26/// A vector of bytes.
27#[derive(Any, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[cfg_attr(feature = "musli", derive(Encode, Decode), musli(transparent))]
29#[rune(item = ::std::bytes)]
30pub struct Bytes {
31    #[cfg_attr(feature = "musli", musli(bytes))]
32    bytes: Vec<u8>,
33}
34
35impl Bytes {
36    /// Construct a new byte array.
37    ///
38    /// # Examples
39    ///
40    /// ```
41    /// use rune::runtime::Bytes;
42    ///
43    /// let bytes = Bytes::new();
44    /// assert_eq!(bytes, b"");
45    /// ```
46    #[inline]
47    pub const fn new() -> Self {
48        Bytes { bytes: Vec::new() }
49    }
50
51    /// Construct a byte array with the given preallocated capacity.
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use rune::runtime::Bytes;
57    ///
58    /// let mut bytes = Bytes::with_capacity(32)?;
59    /// assert_eq!(bytes, b"");
60    /// bytes.extend(b"abcd")?;
61    /// assert_eq!(bytes, b"abcd");
62    /// # Ok::<_, rune::support::Error>(())
63    /// ```
64    #[inline]
65    pub fn with_capacity(cap: usize) -> alloc::Result<Self> {
66        Ok(Self {
67            bytes: Vec::try_with_capacity(cap)?,
68        })
69    }
70
71    /// Convert the byte array into a vector of bytes.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use rune::runtime::Bytes;
77    /// use rune::alloc::prelude::*;
78    /// use rune::alloc::try_vec;
79    ///
80    /// let bytes = Bytes::from_vec(try_vec![b'a', b'b', b'c', b'd']);
81    /// assert_eq!(bytes.into_vec(), [b'a', b'b', b'c', b'd']);
82    /// # Ok::<_, rune::support::Error>(())
83    /// ```
84    #[inline]
85    pub fn into_vec(self) -> Vec<u8> {
86        self.bytes
87    }
88
89    /// Access bytes as a slice.
90    ///
91    /// # Examples
92    ///
93    /// ```
94    /// use rune::runtime::Bytes;
95    /// use rune::alloc::try_vec;
96    ///
97    /// let bytes = Bytes::from_vec(try_vec![b'a', b'b', b'c', b'd']);
98    /// assert_eq!(bytes.as_slice(), &[b'a', b'b', b'c', b'd']);
99    /// # Ok::<_, rune::support::Error>(())
100    /// ```
101    #[inline]
102    pub fn as_slice(&self) -> &[u8] {
103        &self.bytes
104    }
105
106    /// Convert a slice into bytes.
107    ///
108    /// Calling this function allocates bytes internally.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use rune::runtime::Bytes;
114    ///
115    /// let bytes = Bytes::from_slice(vec![b'a', b'b', b'c', b'd'])?;
116    /// assert_eq!(bytes, b"abcd");
117    ///
118    /// # Ok::<_, rune::support::Error>(())
119    /// ```
120    #[inline]
121    pub fn from_slice<B>(bytes: B) -> alloc::Result<Self>
122    where
123        B: AsRef<[u8]>,
124    {
125        Ok(Self {
126            bytes: Vec::try_from(bytes.as_ref())?,
127        })
128    }
129
130    /// Convert a byte array into bytes.
131    ///
132    /// # Examples
133    ///
134    /// ```
135    /// use rune::runtime::Bytes;
136    /// use rune::alloc::try_vec;
137    ///
138    /// let bytes = Bytes::from_vec(try_vec![b'a', b'b', b'c', b'd']);
139    /// assert_eq!(bytes, b"abcd");
140    /// # Ok::<_, rune::support::Error>(())
141    /// ```
142    #[inline]
143    pub fn from_vec(bytes: Vec<u8>) -> Self {
144        Self { bytes }
145    }
146
147    /// Extend these bytes with another collection of bytes.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// use rune::runtime::Bytes;
153    /// use rune::alloc::try_vec;
154    ///
155    /// let mut bytes = Bytes::from_vec(try_vec![b'a', b'b', b'c', b'd']);
156    /// bytes.extend(b"efgh");
157    /// assert_eq!(bytes, b"abcdefgh");
158    /// # Ok::<_, rune::support::Error>(())
159    /// ```
160    pub fn extend<O>(&mut self, other: O) -> alloc::Result<()>
161    where
162        O: AsRef<[u8]>,
163    {
164        self.bytes.try_extend_from_slice(other.as_ref())
165    }
166
167    /// Test if the collection is empty.
168    ///
169    /// # Examples
170    ///
171    /// ```
172    /// use rune::runtime::Bytes;
173    ///
174    /// let mut bytes = Bytes::new();
175    /// assert!(bytes.is_empty());
176    /// ```
177    pub fn is_empty(&self) -> bool {
178        self.bytes.is_empty()
179    }
180
181    /// Get the length of the bytes collection.
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use rune::runtime::Bytes;
187    ///
188    /// let mut bytes = Bytes::new();
189    /// assert_eq!(bytes.len(), 0);
190    /// bytes.extend(b"abcd");
191    /// assert_eq!(bytes.len(), 4);
192    /// ```
193    pub fn len(&self) -> usize {
194        self.bytes.len()
195    }
196
197    /// Get the capacity of the bytes collection.
198    pub fn capacity(&self) -> usize {
199        self.bytes.capacity()
200    }
201
202    /// Get the bytes collection.
203    pub fn clear(&mut self) {
204        self.bytes.clear();
205    }
206
207    /// Reserve additional space.
208    ///
209    /// The exact amount is unspecified.
210    pub fn reserve(&mut self, additional: usize) -> alloc::Result<()> {
211        self.bytes.try_reserve(additional)
212    }
213
214    /// Resever additional space to the exact amount specified.
215    pub fn reserve_exact(&mut self, additional: usize) -> alloc::Result<()> {
216        self.bytes.try_reserve_exact(additional)
217    }
218
219    /// Shrink to fit the amount of bytes in the container.
220    pub fn shrink_to_fit(&mut self) -> alloc::Result<()> {
221        self.bytes.try_shrink_to_fit()
222    }
223
224    /// Pop the last byte.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use rune::runtime::Bytes;
230    ///
231    /// let mut bytes = Bytes::from_slice(b"abcd")?;
232    /// assert_eq!(bytes.pop(), Some(b'd'));
233    /// assert_eq!(bytes, b"abc");
234    /// # Ok::<_, rune::support::Error>(())
235    /// ```
236    pub fn pop(&mut self) -> Option<u8> {
237        self.bytes.pop()
238    }
239
240    /// Append a byte to the back.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// use rune::runtime::Bytes;
246    ///
247    /// let mut bytes = Bytes::from_slice(b"abcd")?;
248    /// bytes.push(b'e');
249    /// assert_eq!(bytes, b"abcde");
250    /// # Ok::<_, rune::support::Error>(())
251    /// ```
252    pub fn push(&mut self, value: u8) -> alloc::Result<()> {
253        self.bytes.try_push(value)
254    }
255
256    /// Removes the byte at the specified index.
257    ///
258    /// # Panics
259    ///
260    /// Panics if `index` is out of bounds.
261    ///
262    /// # Examples
263    ///
264    /// ```
265    /// use rune::runtime::Bytes;
266    ///
267    /// let mut bytes = Bytes::from_slice(b"abcd")?;
268    /// bytes.remove(2);
269    /// assert_eq!(bytes, b"abd");
270    /// # Ok::<_, rune::support::Error>(())
271    /// ```
272    pub fn remove(&mut self, index: usize) -> u8 {
273        self.bytes.remove(index)
274    }
275
276    /// Inserts a byte at position index within the vector, shifting all
277    /// elements after it to the right.
278    ///
279    /// # Panics
280    ///
281    /// Panics if `index` is out of bounds.
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// use rune::runtime::Bytes;
287    ///
288    /// let mut bytes = Bytes::from_slice(b"abcd")?;
289    /// bytes.insert(2, b'e');
290    /// assert_eq!(bytes, b"abecd");
291    /// # Ok::<_, rune::support::Error>(())
292    /// ```
293    pub fn insert(&mut self, index: usize, value: u8) -> alloc::Result<()> {
294        self.bytes.try_insert(index, value)
295    }
296
297    /// Returns a subslice of Bytes.
298    ///
299    /// -  If given a position, returns the byte at that position or `None` if
300    ///    out of bounds.
301    /// - If given a range, returns the subslice corresponding to that range, or
302    ///   `None` if out of bounds.
303    pub(crate) fn index_get(&self, index: Value) -> Result<Option<Value>, VmError> {
304        bytes_slice_index_get(&self.bytes, index)
305    }
306
307    /// Set by index
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// use rune::runtime::Bytes;
313    ///
314    /// let mut bytes = Bytes::from_slice(b"abcd")?;
315    /// bytes.set(0, b'A');
316    /// assert_eq!(bytes, b"Abcd");
317    /// # Ok::<_, rune::support::Error>(())
318    /// ```
319    pub fn set(&mut self, index: usize, value: u8) -> Result<(), VmError> {
320        let Some(v) = self.bytes.get_mut(index) else {
321            return Err(VmError::new(VmErrorKind::OutOfRange {
322                index: index.into(),
323                length: self.len().into(),
324            }));
325        };
326
327        *v = value;
328        Ok(())
329    }
330
331    /// Get the first byte.
332    ///
333    /// # Examples
334    ///
335    /// ```
336    /// use rune::runtime::Bytes;
337    ///
338    /// let bytes = Bytes::from_slice(b"abcd")?;
339    /// assert_eq!(bytes.first(), Some(b'a'));
340    /// # Ok::<_, rune::support::Error>(())
341    /// ```
342    pub fn first(&self) -> Option<u8> {
343        self.bytes.first().copied()
344    }
345
346    /// Get the last byte.
347    ///
348    /// # Examples
349    ///
350    /// ```
351    /// use rune::runtime::Bytes;
352    ///
353    /// let bytes = Bytes::from_slice(b"abcd")?;
354    /// assert_eq!(bytes.last(), Some(b'd'));
355    /// # Ok::<_, rune::support::Error>(())
356    /// ```
357    pub fn last(&self) -> Option<u8> {
358        self.bytes.last().copied()
359    }
360}
361
362impl TryClone for Bytes {
363    #[inline]
364    fn try_clone(&self) -> alloc::Result<Self> {
365        Ok(Self {
366            bytes: self.bytes.try_clone()?,
367        })
368    }
369}
370
371impl From<Vec<u8>> for Bytes {
372    #[inline]
373    fn from(bytes: Vec<u8>) -> Self {
374        Self { bytes }
375    }
376}
377
378impl TryFrom<&[u8]> for Bytes {
379    type Error = alloc::Error;
380
381    #[inline]
382    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
383        let mut bytes = Vec::try_with_capacity(value.len())?;
384        bytes.try_extend_from_slice(value)?;
385        Ok(Self { bytes })
386    }
387}
388
389impl TryFrom<rust_alloc::vec::Vec<u8>> for Bytes {
390    type Error = alloc::Error;
391
392    #[inline]
393    fn try_from(bytes: rust_alloc::vec::Vec<u8>) -> Result<Self, Self::Error> {
394        Ok(Self {
395            bytes: Vec::try_from(bytes)?,
396        })
397    }
398}
399
400impl From<Box<[u8]>> for Bytes {
401    #[inline]
402    fn from(bytes: Box<[u8]>) -> Self {
403        Self {
404            bytes: Vec::from(bytes),
405        }
406    }
407}
408
409impl TryFrom<rust_alloc::boxed::Box<[u8]>> for Bytes {
410    type Error = alloc::Error;
411
412    #[inline]
413    fn try_from(bytes: rust_alloc::boxed::Box<[u8]>) -> Result<Self, Self::Error> {
414        Ok(Self {
415            bytes: Vec::try_from(bytes.as_ref())?,
416        })
417    }
418}
419
420impl fmt::Debug for Bytes {
421    #[inline]
422    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
423        fmt.debug_list().entries(&self.bytes).finish()
424    }
425}
426
427impl ops::Deref for Bytes {
428    type Target = [u8];
429
430    #[inline]
431    fn deref(&self) -> &Self::Target {
432        &self.bytes
433    }
434}
435
436impl ops::DerefMut for Bytes {
437    #[inline]
438    fn deref_mut(&mut self) -> &mut Self::Target {
439        &mut self.bytes
440    }
441}
442
443impl AsRef<[u8]> for Bytes {
444    #[inline]
445    fn as_ref(&self) -> &[u8] {
446        &self.bytes
447    }
448}
449
450impl UnsafeToRef for [u8] {
451    type Guard = RawAnyGuard;
452
453    #[inline]
454    unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError> {
455        let (value, guard) = Ref::into_raw(value.into_ref::<Bytes>()?);
456        Ok((value.as_ref().as_slice(), guard))
457    }
458}
459
460impl<const N: usize> PartialEq<[u8; N]> for Bytes {
461    #[inline]
462    fn eq(&self, other: &[u8; N]) -> bool {
463        self.bytes == other[..]
464    }
465}
466
467impl<const N: usize> PartialEq<&[u8; N]> for Bytes {
468    #[inline]
469    fn eq(&self, other: &&[u8; N]) -> bool {
470        self.bytes == other[..]
471    }
472}
473
474impl<const N: usize> PartialEq<Bytes> for [u8; N] {
475    #[inline]
476    fn eq(&self, other: &Bytes) -> bool {
477        self[..] == other.bytes
478    }
479}
480
481impl<const N: usize> PartialEq<Bytes> for &[u8; N] {
482    #[inline]
483    fn eq(&self, other: &Bytes) -> bool {
484        self[..] == other.bytes
485    }
486}
487
488impl PartialEq<[u8]> for Bytes {
489    #[inline]
490    fn eq(&self, other: &[u8]) -> bool {
491        self.bytes == other
492    }
493}
494
495impl PartialEq<Bytes> for [u8] {
496    #[inline]
497    fn eq(&self, other: &Bytes) -> bool {
498        self == other.bytes
499    }
500}
501
502#[cfg(feature = "serde")]
503impl ser::Serialize for Bytes {
504    #[inline]
505    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
506    where
507        S: ser::Serializer,
508    {
509        serializer.serialize_bytes(&self.bytes)
510    }
511}
512
513#[cfg(feature = "serde")]
514impl<'de> de::Deserialize<'de> for Bytes {
515    #[inline]
516    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
517    where
518        D: de::Deserializer<'de>,
519    {
520        struct Visitor;
521
522        impl de::Visitor<'_> for Visitor {
523            type Value = Bytes;
524
525            #[inline]
526            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
527                write!(f, "a byte array")
528            }
529
530            #[inline]
531            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
532            where
533                E: de::Error,
534            {
535                Bytes::from_slice(v).map_err(E::custom)
536            }
537        }
538
539        deserializer.deserialize_bytes(Visitor)
540    }
541}
542
543impl TryFrom<&[u8]> for Value {
544    type Error = alloc::Error;
545
546    #[inline]
547    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
548        Value::new(Bytes::try_from(value)?)
549    }
550}
551
552/// This is a common index get implementation that is helpfull for custom type to impl `INDEX_GET` protocol.
553pub fn bytes_slice_index_get(this: &[u8], index: Value) -> Result<Option<Value>, VmError> {
554    let slice: Option<&[u8]> = 'out: {
555        if let Some(value) = index.as_any() {
556            match value.type_hash() {
557                RangeFrom::HASH => {
558                    let range = value.borrow_ref::<RangeFrom>()?;
559                    let start = range.start.as_usize()?;
560                    break 'out this.get(start..);
561                }
562                RangeFull::HASH => {
563                    _ = value.borrow_ref::<RangeFull>()?;
564                    break 'out this.get(..);
565                }
566                RangeInclusive::HASH => {
567                    let range = value.borrow_ref::<RangeInclusive>()?;
568                    let start = range.start.as_usize()?;
569                    let end = range.end.as_usize()?;
570                    break 'out this.get(start..=end);
571                }
572                RangeToInclusive::HASH => {
573                    let range = value.borrow_ref::<RangeToInclusive>()?;
574                    let end = range.end.as_usize()?;
575                    break 'out this.get(..=end);
576                }
577                RangeTo::HASH => {
578                    let range = value.borrow_ref::<RangeTo>()?;
579                    let end = range.end.as_usize()?;
580                    break 'out this.get(..end);
581                }
582                Range::HASH => {
583                    let range = value.borrow_ref::<Range>()?;
584                    let start = range.start.as_usize()?;
585                    let end = range.end.as_usize()?;
586                    break 'out this.get(start..end);
587                }
588                _ => {}
589            }
590        };
591
592        let index = usize::from_value(index)?;
593
594        let Some(value) = this.get(index) else {
595            return Ok(None);
596        };
597
598        return Ok(Some((*value).into()));
599    };
600
601    let Some(values) = slice else {
602        return Ok(None);
603    };
604
605    let bytes = Bytes::try_from(values)?;
606    Ok(Some(bytes.try_into()?))
607}