8000 rune: Store Bytes in AnyObj instead of Mutable (relates #844) · rune-rs/rune@88c4de1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 88c4de1

Browse files
committed
rune: Store Bytes in AnyObj instead of Mutable (relates #844)
1 parent cdd8b4b commit 88c4de1

File tree

11 files changed

+171
-93
lines changed

11 files changed

+171
-93
lines changed

crates/rune/src/compile/context.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,24 +303,29 @@ impl Context {
303303
pub fn with_config(#[allow(unused)] stdio: bool) -> Result<Self, ContextError> {
304304
let mut this = Self::new();
305305

306+
// NB: Order is important, since later modules might use types defined
307+
// in previous modules.
308+
306309
this.install(crate::modules::iter::module()?)?;
307-
// This must go first, because it includes types which are used in other modules.
308310
this.install(crate::modules::core::module()?)?;
309-
311+
this.install(crate::modules::cmp::module()?)?;
312+
this.install(crate::modules::any::module()?)?;
310313
this.install(crate::modules::clone::module()?)?;
311314
this.install(crate::modules::num::module()?)?;
312-
this.install(crate::modules::any::module()?)?;
313-
this.install(crate::modules::bytes::module()?)?;
314-
this.install(crate::modules::char::module()?)?;
315315
this.install(crate::modules::hash::module()?)?;
316-
this.install(crate::modules::cmp::module()?)?;
316+
317+
this.install(crate::modules::string::module()?)?;
318+
this.install(crate::modules::bytes::module()?)?;
319+
317320
this.install(crate::modules::collections::module()?)?;
318321
#[cfg(feature = "alloc")]
319322
this.install(crate::modules::collections::hash_map::module()?)?;
320323
#[cfg(feature = "alloc")]
321324
this.install(crate::modules::collections::hash_set::module()?)?;
322325
#[cfg(feature = "alloc")]
323326
this.install(crate::modules::collections::vec_deque::module()?)?;
327+
328+
this.install(crate::modules::char::module()?)?;
324329
this.install(crate::modules::f64::module()?)?;
325330
this.install(crate::modules::tuple::module()?)?;
326331
this.install(crate::modules::fmt::module()?)?;
@@ -336,7 +341,6 @@ impl Context {
336341
this.install(crate::modules::option::module()?)?;
337342
this.install(crate::modules::result::module()?)?;
338343
this.install(crate::modules::stream::module()?)?;
339-
this.install(crate::modules::string::module()?)?;
340344
this.install(crate::modules::test::module()?)?;
341345
this.install(crate::modules::vec::module()?)?;
342346
this.install(crate::modules::slice::module()?)?;

crates/rune/src/modules/bytes.rs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
//! The bytes module.
22
3+
use core::cmp::Ordering;
4+
35
use crate as rune;
6+
use crate::alloc::fmt::TryWrite;
47
use crate::alloc::prelude::*;
58
use crate::alloc::Vec;
6-
use crate::runtime::{Bytes, VmResult};
9+
use crate::runtime::{Bytes, Formatter, Hasher, VmResult};
710
use crate::{ContextError, Module};
811

912
/// The bytes module.
@@ -32,6 +35,22 @@ pub fn module() -> Result<Module, ContextError> {
3235
m.function_meta(clone__meta)?;
3336
m.implement_trait::<Bytes>(rune::item!(::std::clone::Clone))?;
3437

38+
m.function_meta(partial_eq__meta)?;
39+
m.implement_trait::<Bytes>(rune::item!(::std::cmp::PartialEq))?;
40+
41+
m.function_meta(eq__meta)?;
42+
m.implement_trait::<Bytes>(rune::item!(::std::cmp::Eq))?;
43+
44+
m.function_meta(partial_cmp__meta)?;
45+
m.implement_trait::<Bytes>(rune::item!(::std::cmp::PartialOrd))?;
46+
47+
m.function_meta(cmp__meta)?;
48+
m.implement_trait::<Bytes>(rune::item!(::std::cmp::Ord))?;
49+
50+
m.function_meta(hash__meta)?;
51+
52+
m.function_meta(string_debug__meta)?;
53+
3554
Ok(m)
3655
}
3756

@@ -317,6 +336,114 @@ fn clone(this: &Bytes) -> VmResult<Bytes> {
317336
VmResult::Ok(vm_try!(this.try_clone()))
318337
}
319338

339+
/// Test two byte arrays for partial equality.
340+
///
341+
/// # Examples
342+
///
343+
/// ```rune
344+
/// use std::ops::partial_eq;
345+
///
346+
/// assert_eq!(partial_eq(b"a", b"a"), true);
347+
/// assert_eq!(partial_eq(b"a", b"ab"), false);
348+
/// assert_eq!(partial_eq(b"ab", b"a"), false);
349+
/// ```
350+
#[rune::function(keep, instance, protocol = PARTIAL_EQ)]
351+
#[inline]
352+
fn partial_eq(this: &[u8], rhs: &[u8]) -> bool {
353+
this.eq(rhs)
354+
}
355+
356+
/// Test two byte arrays for total equality.
357+
///
358+
/// # Examples
359+
///
360+
/// ```rune
361+
/// use std::ops::eq;
362+
///
363+
/// assert_eq!(eq(b"a", b"a"), true);
364+
/// assert_eq!(eq(b"a", b"ab"), false);
365+
/// assert_eq!(eq(b"ab", b"a"), false);
366+
/// ```
367+
#[rune::function(keep, instance, protocol = EQ)]
368+
#[inline]
369+
fn eq(this: &[u8], rhs: &[u8]) -> bool {
370+
this.eq(rhs)
371+
}
372+
373+
/// Perform a partial ordered comparison between two byte arrays.
374+
///
375+
/// # Examples
376+
///
377+
/// ```rune
378+
/// assert!(b"a" < b"ab");
379+
/// assert!(b"ab" > b"a");
380+
/// assert!(b"a" == b"a");
381+
/// ```
382+
///
383+
/// Using explicit functions:
384+
///
385+
/// ```rune
386+
/// use std::cmp::Ordering;
387+
/// use std::ops::partial_cmp;
388+
///
389+
/// assert_eq!(partial_cmp(b"a", b"ab"), Some(Ordering::Less));
390+
/// assert_eq!(partial_cmp(b"ab", b"a"), Some(Ordering::Greater));
391+
/// assert_eq!(partial_cmp(b"a", b"a"), Some(Ordering::Equal));
392+
/// ```
393+
#[rune::function(keep, instance, protocol = PARTIAL_CMP)]
394+
#[inline]
395+
fn partial_cmp(this: &[u8], rhs: &[u8]) -> Option<Ordering> {
396+
this.partial_cmp(rhs)
397+
}
398+
399+
/// Perform a totally ordered comparison between two byte arrays.
400+
///
401+
/// # Examples
402+
///
403+
/// ```rune
404+
/// use std::cmp::Ordering;
405+
/// use std::ops::cmp;
406+
///
407+
/// assert_eq!(cmp(b"a", b"ab"), Ordering::Less);
408+
/// assert_eq!(cmp(b"ab", b"a"), Ordering::Greater);
409+
/// assert_eq!(cmp(b"a", b"a"), Ordering::Equal);
410+
/// ```
411+
#[rune::function(keep, instance, protocol = CMP)]
412+
#[inline]
413+
fn cmp(this: &[u8], rhs: &[u8]) -> Ordering {
414+
this.cmp(rhs)
415+
}
416+
417+
/// Hash the string.
418+
///
419+
/// # Examples
420+
///
421+
/// ```rune
422+
/// use std::ops::hash;
423+
///
424+
/// let a = "hello";
425+
/// let b = "hello";
426+
///
427+
/// assert_eq!(hash(a), hash(b));
428+
/// ```
429+
#[rune::function(keep, instance, protocol = HASH)]
430+
fn hash(this: &[u8], hasher: &mut Hasher) {
431+
hasher.write(this);
432+
}
433+
434+
/// Write a debug representation of a byte array.
435+
///
436+
/// # Examples
437+
///
438+
/// ```rune
439+
/// println!("{:?}", b"Hello");
440+
/// ```
441+
#[rune::function(keep, instance, protocol = STRING_DEBUG)]
442+
#[inline]
443+
fn string_debug(this: &[u8], f: &mut Formatter) -> VmResult<()> {
444+
rune::vm_write!(f, "{this:?}")
445+
}
446+
320447
/// Shrinks the capacity of the byte array as much as possible.
321448
///
322449
/// It will drop down as close as possible to the length but the allocator may

crates/rune/src/modules/collections/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ use crate::{ContextError, Module};
2323
pub fn module() -> Result<Module, ContextError> {
2424
let mut m = Module::from_meta(self::module_meta)?;
2525

26+
#[cfg(feature = "alloc")]
2627
m.reexport(
2728
["HashMap"],
2829
rune::item!(::std::collections::hash_map::HashMap),
2930
)?;
3031

32+
#[cfg(feature = "alloc")]
3133
m.reexport(
3234
["HashSet"],
3335
rune::item!(::std::collections::hash_set::HashSet),
3436
)?;
3537

38+
#[cfg(feature = "alloc")]
3639
m.reexport(
3740
["VecDeque"],
3841
rune::item!(::std::collections::vec_deque::VecDeque),

crates/rune/src/runtime/borrow_mut.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ impl<'a, T: ?Sized> BorrowMut<'a, T> {
4444
/// use rune::alloc::try_vec;
4545
///
4646
/// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
47-
/// let bytes = bytes.borrow_bytes_mut()?;
47+
/// let bytes = bytes.borrow_any_mut::<Bytes>()?;
4848
///
49-
/// let mut bytes: BorrowMut<[u8]> = BorrowMut::map(bytes, |bytes| &mut bytes[0..2]);
49+
/// let mut bytes = BorrowMut::map(bytes, |bytes| &mut bytes[0..2]);
5050
///
5151
/// assert_eq!(&mut bytes[..], &mut [1u8, 2u8][..]);
5252
/// # Ok::<_, rune::support::Error>(())
@@ -71,7 +71,7 @@ impl<'a, T: ?Sized> BorrowMut<'a, T> {
7171
/// use rune::alloc::try_vec;
7272
///
7373
/// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
74-
/// let bytes = bytes.borrow_bytes_mut()?;
74+
/// let bytes = bytes.borrow_any_mut::<Bytes>()?;
7575
///
7676
/// let Ok(mut bytes) = BorrowMut::try_map(bytes, |bytes| bytes.get_mut(0..2)) else {
7777
/// panic!("Conversion failed");

crates/rune/src/runtime/borrow_ref.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<'a, T: ?Sized> BorrowRef<'a, T> {
4141
/// use rune::alloc::try_vec;
4242
///
4343
/// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
44-
/// let bytes = bytes.borrow_bytes_ref()?;
44+
/// let bytes = bytes.borrow_any_ref::<Bytes>()?;
4545
///
4646
/// let bytes: BorrowRef<[u8]> = BorrowRef::map(bytes, |bytes| &bytes[0..2]);
4747
///
@@ -67,7 +67,7 @@ impl<'a, T: ?Sized> BorrowRef<'a, T> {
6767
/// use rune::alloc::try_vec;
6868
///
6969
/// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
70-
/// let bytes = bytes.borrow_bytes_ref()?;
70+
/// let bytes = bytes.borrow_any_ref::<Bytes>()?;
7171
///
7272
/// let Ok(bytes) = BorrowRef::try_map(bytes, |bytes| bytes.get(0..2)) else {
7373
/// panic!("Conversion failed");

crates/rune/src/runtime/bytes.rs

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//!
33
//! [Value::Bytes]: crate::Value::Bytes.
44
5-
use core::cmp;
65
use core::fmt;
76
use core::ops;
87

@@ -12,16 +11,14 @@ use serde::ser;
1211
use crate as rune;
1312
use crate::alloc::prelude::*;
1413
use crate::alloc::{self, Box, Vec};
15-
use crate::runtime::{
16-
Mutable, RawAnyGuard, Ref, UnsafeToRef, Value, ValueRepr, VmErrorKind, VmResult,
17-
};
14+
use crate::runtime::{RawAnyGuard, Ref, UnsafeToRef, Value, VmResult};
1815
use crate::Any;
1916

2017
/// A vector of bytes.
2118
#[derive(Default, Any, PartialEq, Eq, PartialOrd, Ord, Hash)]
22-
#[rune(builtin, static_type = BYTES)]
19+
#[rune(static_type = BYTES)]
2320
pub struct Bytes {
24-
pub(crate) bytes: Vec<u8>,
21+
bytes: Vec<u8>,
2522
}
2623

2724
impl Bytes {
@@ -266,6 +263,7 @@ impl Bytes {
266263
}
267264

268265
impl TryClone for Bytes {
266+
#[inline]
269267
fn try_clone(&self) -> alloc::Result<Self> {
270268
Ok(Self {
271269
bytes: self.bytes.try_clone()?,
@@ -355,73 +353,51 @@ impl AsRef<[u8]> for Bytes {
355353
}
356354
}
357355

358-
from_value2!(Bytes, into_bytes_ref, into_bytes_mut, into_bytes);
359-
360356
impl UnsafeToRef for [u8] {
361357
type Guard = RawAnyGuard;
362358

363359
unsafe fn unsafe_to_ref<'a>(value: Value) -> VmResult<(&'a Self, Self::Guard)> {
364-
let value = match vm_try!(value.into_repr()) {
365-
ValueRepr::Inline(value) => {
366-
return VmResult::expected::<Bytes>(value.type_info());
367-
}
368-
ValueRepr::Mutable(value) => vm_try!(value.into_ref()),
369-
ValueRepr::Any(value) => {
370-
return VmResult::expected::<Bytes>(value.type_info());
371-
}
372-
};
373-
374-
let result = Ref::try_map(value, |value| match value {
375-
Mutable::Bytes(bytes) => Some(bytes.as_slice()),
376-
_ => None,
377-
});
378-
379-
match result {
380-
Ok(bytes) => {
381-
let (value, guard) = Ref::into_raw(bytes);
382-
VmResult::Ok((value.as_ref(), guard))
383-
}
384-
Err(actual) => VmResult::err(VmErrorKind::expected::<Bytes>(actual.type_info())),
385-
}
360+
let (value, guard) = Ref::into_raw(vm_try!(value.into_any_ref::<Bytes>()));
361+
VmResult::Ok((value.as_ref().as_slice(), guard))
386362
}
387363
}
388364

389-
impl<const N: usize> cmp::PartialEq<[u8; N]> for Bytes {
365+
impl<const N: usize> PartialEq<[u8; N]> for Bytes {
390366
#[inline]
391367
fn eq(&self, other: &[u8; N]) -> bool {
392368
self.bytes == other[..]
393369
}
394370
}
395371

396-
impl<const N: usize> cmp::PartialEq<&[u8; N]> for Bytes {
372+
impl<const N: usize> PartialEq<&[u8; N]> for Bytes {
397373
#[inline]
398374
fn eq(&self, other: &&[u8; N]) -> bool {
399375
self.bytes == other[..]
400376
}
401377
}
402378

403-
impl<const N: usize> cmp::PartialEq<Bytes> for [u8; N] {
379+
impl<const N: usize> PartialEq<Bytes> for [u8; N] {
404380
#[inline]
405381
fn eq(&self, other: &Bytes) -> bool {
406382
self[..] == other.bytes
407383
}
408384
}
409385

410-
impl<const N: usize> cmp::PartialEq<Bytes> for &[u8; N] {
386+
impl<const N: usize> PartialEq<Bytes> for &[u8; N] {
411387
#[inline]
412388
fn eq(&self, other: &Bytes) -> bool {
413389
self[..] == other.bytes
414390
}
415391
}
416392

417-
impl cmp::PartialEq<[u8]> for Bytes {
393+
impl PartialEq<[u8]> for Bytes {
418394
#[inline]
419395
fn eq(&self, other: &[u8]) -> bool {
420396
self.bytes == other
421397
}
422398
}
423399

424-
impl cmp::PartialEq<Bytes> for [u8] {
400+
impl PartialEq<Bytes> for [u8] {
425401
#[inline]
426402
fn eq(&self, other: &Bytes) -> bool {
427403
self == other.bytes

crates/rune/src/runtime/const_value.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ impl ConstValue {
5959
Some(some) => Some(vm_try!(Box::try_new(vm_try!(Self::from_value_ref(some))))),
6060
None => None,
6161
}),
62-
Mutable::Bytes(ref bytes) => Self::Bytes(vm_try!(bytes.try_clone())),
6362
Mutable::Vec(ref vec) => {
6463
let mut const_vec = vm_try!(Vec::try_with_capacity(vec.len()));
6564

@@ -100,6 +99,10 @@ impl ConstValue {
10099
let s = vm_try!(value.borrow_ref::<String>());
101100
Self::String(vm_try!(s.try_to_owned()))
102101
}
102+
Bytes::HASH => {
103+
let s = vm_try!(value.borrow_ref::<Bytes>());
104+
Self::Bytes(vm_try!(s.try_to_owned()))
105+
}
103106
_ => {
104107
return VmResult::err(VmErrorKind::ConstNotSupported {
105108
actual: value.type_info(),

0 commit comments

Comments
 (0)
0