1use 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#[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 #[inline]
47 pub const fn new() -> Self {
48 Bytes { bytes: Vec::new() }
49 }
50
51 #[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 #[inline]
85 pub fn into_vec(self) -> Vec<u8> {
86 self.bytes
87 }
88
89 #[inline]
102 pub fn as_slice(&self) -> &[u8] {
103 &self.bytes
104 }
105
106 #[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 #[inline]
143 pub fn from_vec(bytes: Vec<u8>) -> Self {
144 Self { bytes }
145 }
146
147 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 pub fn is_empty(&self) -> bool {
178 self.bytes.is_empty()
179 }
180
181 pub fn len(&self) -> usize {
194 self.bytes.len()
195 }
196
197 pub fn capacity(&self) -> usize {
199 self.bytes.capacity()
200 }
201
202 pub fn clear(&mut self) {
204 self.bytes.clear();
205 }
206
207 pub fn reserve(&mut self, additional: usize) -> alloc::Result<()> {
211 self.bytes.try_reserve(additional)
212 }
213
214 pub fn reserve_exact(&mut self, additional: usize) -> alloc::Result<()> {
216 self.bytes.try_reserve_exact(additional)
217 }
218
219 pub fn shrink_to_fit(&mut self) -> alloc::Result<()> {
221 self.bytes.try_shrink_to_fit()
222 }
223
224 pub fn pop(&mut self) -> Option<u8> {
237 self.bytes.pop()
238 }
239
240 pub fn push(&mut self, value: u8) -> alloc::Result<()> {
253 self.bytes.try_push(value)
254 }
255
256 pub fn remove(&mut self, index: usize) -> u8 {
273 self.bytes.remove(index)
274 }
275
276 pub fn insert(&mut self, index: usize, value: u8) -> alloc::Result<()> {
294 self.bytes.try_insert(index, value)
295 }
296
297 pub(crate) fn index_get(&self, index: Value) -> Result<Option<Value>, VmError> {
304 bytes_slice_index_get(&self.bytes, index)
305 }
306
307 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 pub fn first(&self) -> Option<u8> {
343 self.bytes.first().copied()
344 }
345
346 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
552pub 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}