diff --git a/crates/rune-macros/src/any.rs b/crates/rune-macros/src/any.rs index dc03bdd3c..e1524a0af 100644 --- a/crates/rune-macros/src/any.rs +++ b/crates/rune-macros/src/any.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; use rune_core::Hash; use syn::punctuated::Punctuated; @@ -50,8 +50,9 @@ impl InternalCall { Err(error) => return Err(vec![error]), }; + let attr = TypeAttr::default(); let name = syn::LitStr::new(&name.to_string(), name.span()); - expand_any(None, &self.path, type_hash, &name, &[], &tokens, &generics) + expand_any(attr, &self.path, type_hash, &name, &[], &tokens, &generics) } } @@ -110,7 +111,7 @@ impl Derive { let name = syn::LitStr::new(&name.to_string(), name.span()); expand_any( - attr.builtin, + attr, ident, type_hash, &name, @@ -470,7 +471,7 @@ fn expand_enum_install_with( /// Expand the necessary implementation details for `Any`. pub(super) fn expand_any( - builtin: Option, + attr: TypeAttr, ident: T, type_hash: Hash, name: &syn::LitStr, @@ -504,12 +505,23 @@ where vm_result, install_with, non_null, + box_, + static_type_mod, + from_value, + raw_ref, + raw_mut, + mut_, + ref_, .. } = &tokens; let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); - let generic_names = generics.type_params().map(|v| &v.ident).collect::>(); + let generic_names = if attr.static_type.is_some() { + vec![] + } else { + generics.type_params().map(|v| &v.ident).collect::>() + }; let impl_named = if !generic_names.is_empty() { quote! { @@ -517,7 +529,7 @@ where impl #impl_generics #named for #ident #type_generics #where_clause { const BASE_NAME: #raw_str = #raw_str::from_str(#name); - fn full_name() -> Box { + fn full_name() -> #box_ { [#name, "<", &#(#generic_names::full_name(),)* ">"].join("").into_boxed_str() } } @@ -541,15 +553,7 @@ where } }; - let any = if builtin.is_none() { - let type_hash = type_hash.into_inner(); - - let make_hash = if !generic_names.is_empty() { - quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_of>::type_hash()),*]))) - } else { - quote!(#hash::new(#type_hash)) - }; - + let impl_type_of = if attr.builtin.is_none() { let type_parameters = if !generic_names.is_empty() { quote!(#hash::parameters([#(<#generic_names as #type_of>::type_hash()),*])) } else { @@ -557,13 +561,6 @@ where }; Some(quote! { - #[automatically_derived] - impl #impl_generics #any for #ident #type_generics #where_clause { - fn type_hash() -> #hash { - #make_hash - } - } - #[automatically_derived] impl #impl_generics #type_of for #ident #type_generics #where_clause { #[inline] @@ -592,6 +589,50 @@ where Some(::type_of()) } } + }) + } else if let Some(ty) = attr.static_type { + Some(quote! { + #[automatically_derived] + impl #impl_generics #type_of for #ident #type_generics #where_clause { + #[inline] + fn type_hash() -> #hash { + #static_type_mod::#ty.hash + } + + #[inline] + fn type_info() -> #type_info { + #type_info::StaticType(#static_type_mod::#ty) + } + } + + #[automatically_derived] + impl #impl_generics #maybe_type_of for #ident #type_generics #where_clause { + #[inline] + fn maybe_type_of() -> Option<#full_type_of> { + Some(::type_of()) + } + } + }) + } else { + None + }; + + let any = if attr.builtin.is_none() { + let type_hash = type_hash.into_inner(); + + let make_hash = if !generic_names.is_empty() { + quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_of>::type_hash()),*]))) + } else { + quote!(#hash::new(#type_hash)) + }; + + Some(quote! { + #[automatically_derived] + impl #impl_generics #any for #ident #type_generics #where_clause { + fn type_hash() -> #hash { + #make_hash + } + } #[automatically_derived] impl #impl_generics #unsafe_to_ref for #ident #type_generics #where_clause { @@ -645,9 +686,82 @@ where None }; + let impl_from_value = 'out: { + if let Some(path) = attr.from_value { + let ty = match &attr.from_value_params { + Some(params) => quote!(#ident<#params>), + None if generics.params.is_empty() => quote!(#ident), + _ => break 'out None, + }; + + Some(quote! { + impl #from_value for #ty { + fn from_value(value: Value) -> #vm_result { + let value = vm_try!(#path(value)); + let value = vm_try!(value.take()); + #vm_result::Ok(value) + } + } + + impl #unsafe_to_ref for #ty { + type Guard = #raw_ref; + + unsafe fn unsafe_to_ref<'a>( + value: #value, + ) -> #vm_result<(&'a Self, Self::Guard)> { + let value = vm_try!(#path(value)); + let value = vm_try!(value.into_ref()); + let (value, guard) = #ref_::into_raw(value); + #vm_result::Ok((value.as_ref(), guard)) + } + } + + impl #unsafe_to_mut for #ty { + type Guard = #raw_mut; + + unsafe fn unsafe_to_mut<'a>( + value: #value, + ) -> #vm_result<(&'a mut Self, Self::Guard)> { + let value = vm_try!(#path(value)); + let value = vm_try!(#shared::into_mut(value)); + let (mut value, guard) = #mut_::into_raw(value); + #vm_result::Ok((value.as_mut(), guard)) + } + } + + impl #from_value for #shared<#ty> { + #[inline] + fn from_value(value: #value) -> #vm_result { + #path(value) + } + } + + impl #from_value for #ref_<#ty> { + fn from_value(value: Value) -> #vm_result { + let value = vm_try!(#path(value)); + let value = vm_try!(#shared::into_ref(value)); + #vm_result::Ok(value) + } + } + + impl #from_value for #mut_<#ty> { + fn from_value(value: Value) -> VmResult { + let value = vm_try!(#path(value)); + let value = vm_try!(#shared::into_mut(value)); + #vm_result::Ok(value) + } + } + }) + } else { + None + } + }; + Ok(quote! { #install_with #impl_named + #impl_type_of + #impl_from_value #any }) } diff --git a/crates/rune-macros/src/context.rs b/crates/rune-macros/src/context.rs index d18ce9cc9..8133a7c56 100644 --- a/crates/rune-macros/src/context.rs +++ b/crates/rune-macros/src/context.rs @@ -79,6 +79,12 @@ pub(crate) struct TypeAttr { /// Indicates that this is a builtin type, so don't generate an `Any` /// implementation for it. pub(crate) builtin: Option, + /// Indicate a static type to use. + pub(crate) static_type: Option, + /// Method to use to convert from value. + pub(crate) from_value: Option, + /// Method to use to convert from value. + pub(crate) from_value_params: Option>, } /// Parsed variant attributes. @@ -455,6 +461,18 @@ impl Context { attr.constructor = true; } else if meta.path == BUILTIN { attr.builtin = Some(meta.path.span()); + } else if meta.path == STATIC_TYPE { + meta.input.parse::()?; + attr.static_type = Some(meta.input.parse()?); + } else if meta.path == FROM_VALUE { + meta.input.parse::()?; + attr.from_value = Some(meta.input.parse()?); + } else if meta.path == FROM_VALUE_PARAMS { + meta.input.parse::()?; + let content; + syn::bracketed!(content in meta.input); + attr.from_value_params = + Some(syn::punctuated::Punctuated::parse_terminated(&content)?); } else { return Err(syn::Error::new_spanned( &meta.path, @@ -545,6 +563,15 @@ impl Context { Span::call_site(), ))); + let mut alloc = syn::Path { + leading_colon: Some(::default()), + segments: Punctuated::default(), + }; + alloc.segments.push(syn::PathSegment::from(syn::Ident::new( + "alloc", + Span::call_site(), + ))); + let mut default_module; let m = match module { @@ -570,6 +597,10 @@ impl Context { compile_error: path(m, ["compile", "Error"]), context_error: path(m, ["compile", "ContextError"]), from_value: path(m, ["runtime", "FromValue"]), + raw_ref: path(m, ["runtime", "RawRef"]), + raw_mut: path(m, ["runtime", "RawMut"]), + ref_: path(m, ["runtime", "Ref"]), + mut_: path(m, ["runtime", "Mut"]), full_type_of: path(m, ["runtime", "FullTypeOf"]), hash: path(m, ["Hash"]), id: path(m, ["parse", "Id"]), @@ -613,6 +644,8 @@ impl Context { double_ended_iterator: path(&core, ["iter", "DoubleEndedIterator"]), option: path(&core, ["option", "Option"]), non_null: path(&core, ["ptr", "NonNull"]), + box_: path(&alloc, ["boxed", "Box"]), + static_type_mod: path(m, ["runtime", "static_type"]), } } } @@ -695,6 +728,12 @@ pub(crate) struct Tokens { pub(crate) double_ended_iterator: syn::Path, pub(crate) option: syn::Path, pub(crate) non_null: syn::Path, + pub(crate) box_: syn::Path, + pub(crate) static_type_mod: syn::Path, + pub(crate) raw_ref: syn::Path, + pub(crate) raw_mut: syn::Path, + pub(crate) ref_: syn::Path, + pub(crate) mut_: syn::Path, } impl Tokens { diff --git a/crates/rune-macros/src/internals.rs b/crates/rune-macros/src/internals.rs index 1b3a2c3e2..8d1771e90 100644 --- a/crates/rune-macros/src/internals.rs +++ b/crates/rune-macros/src/internals.rs @@ -22,6 +22,9 @@ pub const INSTALL_WITH: Symbol = Symbol("install_with"); pub const CONSTRUCTOR: Symbol = Symbol("constructor"); pub const BUILTIN: Symbol = Symbol("builtin"); +pub const STATIC_TYPE: Symbol = Symbol("static_type"); +pub const FROM_VALUE: Symbol = Symbol("from_value"); +pub const FROM_VALUE_PARAMS: Symbol = Symbol("from_value_params"); pub const GET: Symbol = Symbol("get"); pub const SET: Symbol = Symbol("set"); pub const COPY: Symbol = Symbol("copy"); diff --git a/crates/rune/src/internal_macros.rs b/crates/rune/src/internal_macros.rs index 0d62dca54..77e71c03f 100644 --- a/crates/rune/src/internal_macros.rs +++ b/crates/rune/src/internal_macros.rs @@ -10,8 +10,8 @@ macro_rules! resolve_context { /// Build an implementation of `TypeOf` basic of a static type. macro_rules! impl_static_type { - (impl <$($p:ident),*> $ty:ty => $static_type:expr) => { - impl<$($p,)*> $crate::runtime::TypeOf for $ty { + (impl <$($p:ident),*> $ty:ty => $static_type:expr $(, where $($where:tt)+)?) => { + impl<$($p,)*> $crate::runtime::TypeOf for $ty $(where $($where)+)* { #[inline] fn type_hash() -> $crate::Hash { $static_type.hash @@ -23,7 +23,7 @@ macro_rules! impl_static_type { } } - impl<$($p,)*> $crate::runtime::MaybeTypeOf for $ty { + impl<$($p,)*> $crate::runtime::MaybeTypeOf for $ty $(where $($where)+)* { #[inline] fn maybe_type_of() -> Option<$crate::runtime::FullTypeOf> { Some(<$ty as $crate::runtime::TypeOf>::type_of()) diff --git a/crates/rune/src/module/module.rs b/crates/rune/src/module/module.rs index 8801816a8..ea5ad8010 100644 --- a/crates/rune/src/module/module.rs +++ b/crates/rune/src/module/module.rs @@ -241,7 +241,7 @@ impl Module { /// Accessor to modify type metadata such as documentaiton, fields, variants. pub fn type_meta(&mut self) -> Result, ContextError> where - T: Named + TypeOf, + T: ?Sized + Named + TypeOf, { let type_hash = T::type_hash(); diff --git a/crates/rune/src/modules/ops.rs b/crates/rune/src/modules/ops.rs index a5628cd58..6dad232d3 100644 --- a/crates/rune/src/modules/ops.rs +++ b/crates/rune/src/modules/ops.rs @@ -77,26 +77,7 @@ pub fn module() -> Result { m.ty::()?; { - m.ty::>()?.docs([ - "The return value of a function producing a generator.", - "", - "Functions which contain the `yield` keyword produces generators.", - "", - "# Examples", - "", - "```rune", - "use std::ops::Generator;", - "", - "fn generate() {", - " yield 1;", - " yield 2;", - "}", - "", - "let g = generate();", - "assert!(g is Generator)", - "```", - ]); - + m.ty::>()?; m.function_meta(generator_next)?; m.function_meta(generator_resume)?; m.function_meta(generator_iter)?; diff --git a/crates/rune/src/runtime/bytes.rs b/crates/rune/src/runtime/bytes.rs index 7d92e0dea..56dc22932 100644 --- a/crates/rune/src/runtime/bytes.rs +++ b/crates/rune/src/runtime/bytes.rs @@ -10,13 +10,14 @@ use crate::no_std::prelude::*; use serde::{Deserialize, Serialize}; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{RawRef, RawStr, Ref, UnsafeToRef, Value, VmResult}; +use crate as rune; +use crate::runtime::{RawRef, Ref, UnsafeToRef, Value, VmResult}; +use crate::Any; /// A vector of bytes. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] +#[derive(Any, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] #[serde(transparent)] +#[rune(builtin, static_type = BYTES_TYPE)] pub struct Bytes { #[serde(with = "serde_bytes")] pub(crate) bytes: Vec, @@ -304,12 +305,6 @@ impl UnsafeToRef for [u8] { } } -impl Named for Bytes { - const BASE_NAME: RawStr = RawStr::from_str("Bytes"); -} - -impl InstallWith for Bytes {} - impl cmp::PartialEq<[u8; N]> for Bytes { #[inline] fn eq(&self, other: &[u8; N]) -> bool { diff --git a/crates/rune/src/runtime/control_flow.rs b/crates/rune/src/runtime/control_flow.rs index 51b7f698c..65f5e3a05 100644 --- a/crates/rune/src/runtime/control_flow.rs +++ b/crates/rune/src/runtime/control_flow.rs @@ -21,7 +21,7 @@ use crate::Any; /// assert_eq!(c, ControlFlow::Continue(42)); /// ``` #[derive(Debug, Clone, Any)] -#[rune(builtin)] +#[rune(builtin, static_type = CONTROL_FLOW_TYPE)] pub enum ControlFlow { /// Move on to the next phase of the operation as normal. #[rune(constructor)] diff --git a/crates/rune/src/runtime/format.rs b/crates/rune/src/runtime/format.rs index 0e2298978..e341c4396 100644 --- a/crates/rune/src/runtime/format.rs +++ b/crates/rune/src/runtime/format.rs @@ -12,9 +12,9 @@ use crate::no_std::prelude::*; use musli::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{Formatter, FromValue, ProtocolCaller, RawStr, Value, VmErrorKind, VmResult}; +use crate as rune; +use crate::runtime::{Formatter, FromValue, ProtocolCaller, Value, VmErrorKind, VmResult}; +use crate::Any; /// Error raised when trying to parse a type string and it fails. #[derive(Debug, Clone, Copy)] @@ -40,7 +40,8 @@ impl fmt::Display for AlignmentFromStrError { } /// A format specification, wrapping an inner value. -#[derive(Debug, Clone)] +#[derive(Any, Debug, Clone)] +#[rune(builtin, static_type = FORMAT_TYPE)] pub struct Format { /// The value being formatted. pub(crate) value: Value, @@ -48,12 +49,6 @@ pub struct Format { pub(crate) spec: FormatSpec, } -impl Named for Format { - const BASE_NAME: RawStr = RawStr::from_str("Format"); -} - -impl InstallWith for Format {} - impl FromValue for Format { #[inline] fn from_value(value: Value) -> VmResult { diff --git a/crates/rune/src/runtime/function.rs b/crates/rune/src/runtime/function.rs index a7a21e8cc..637ee024c 100644 --- a/crates/rune/src/runtime/function.rs +++ b/crates/rune/src/runtime/function.rs @@ -41,7 +41,7 @@ use crate::Hash; /// ``` #[derive(Any)] #[repr(transparent)] -#[rune(builtin)] +#[rune(builtin, static_type = FUNCTION_TYPE)] pub struct Function(FunctionImpl); impl Function { diff --git a/crates/rune/src/runtime/future.rs b/crates/rune/src/runtime/future.rs index f781bbd93..c511d267b 100644 --- a/crates/rune/src/runtime/future.rs +++ b/crates/rune/src/runtime/future.rs @@ -5,9 +5,9 @@ use core::task::{Context, Poll}; use crate::no_std::prelude::*; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{RawStr, ToValue, Value, VmErrorKind, VmResult}; +use crate as rune; +use crate::runtime::{ToValue, Value, VmErrorKind, VmResult}; +use crate::Any; use pin_project::pin_project; @@ -16,6 +16,8 @@ type DynFuture = dyn future::Future> + 'static; /// A type-erased future that can only be unsafely polled in combination with /// the virtual machine that created it. +#[derive(Any)] +#[rune(builtin, static_type = FUTURE_TYPE, from_value = Value::into_future)] pub struct Future { future: Option>>, } @@ -109,11 +111,3 @@ where } } } - -from_value!(Future, into_future); - -impl Named for Future { - const BASE_NAME: RawStr = RawStr::from_str("Future"); -} - -impl InstallWith for Future {} diff --git a/crates/rune/src/runtime/generator.rs b/crates/rune/src/runtime/generator.rs index 415b9532f..b494c03cc 100644 --- a/crates/rune/src/runtime/generator.rs +++ b/crates/rune/src/runtime/generator.rs @@ -1,13 +1,29 @@ use core::fmt; use core::iter; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{ - GeneratorState, Iterator, RawStr, Value, Vm, VmErrorKind, VmExecution, VmResult, -}; - -/// A generator with a stored virtual machine. +use crate as rune; +use crate::runtime::{GeneratorState, Iterator, Value, Vm, VmErrorKind, VmExecution, VmResult}; +use crate::Any; + +/// The return value of a function producing a generator. +/// +/// Functions which contain the `yield` keyword produces generators. +/// +/// # Examples +/// +/// ```rune +/// use std::ops::Generator; +/// +/// fn generate() { +/// yield 1; +/// yield 2; +/// } +/// +/// let g = generate(); +/// assert!(g is Generator) +/// ``` +#[derive(Any)] +#[rune(builtin, static_type = GENERATOR_TYPE, from_value = Value::into_generator, from_value_params = [Vm])] pub struct Generator where T: AsRef + AsMut, @@ -116,14 +132,3 @@ where .finish() } } - -impl Named for Generator -where - T: AsRef + AsMut, -{ - const BASE_NAME: RawStr = RawStr::from_str("Generator"); -} - -impl InstallWith for Generator where T: AsRef + AsMut {} - -from_value!(Generator, into_generator); diff --git a/crates/rune/src/runtime/generator_state.rs b/crates/rune/src/runtime/generator_state.rs index ca49906b7..ccaf28cb7 100644 --- a/crates/rune/src/runtime/generator_state.rs +++ b/crates/rune/src/runtime/generator_state.rs @@ -1,6 +1,6 @@ -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{ProtocolCaller, RawStr, Value, VmResult}; +use crate as rune; +use crate::runtime::{ProtocolCaller, Value, VmResult}; +use crate::Any; /// The state of a generator. /// @@ -48,7 +48,8 @@ use crate::runtime::{ProtocolCaller, RawStr, Value, VmResult}; /// assert_eq!(ret, 42); /// # Ok::<_, rune::Error>(()) /// ``` -#[derive(Debug)] +#[derive(Any, Debug)] +#[rune(builtin, static_type = GENERATOR_STATE_TYPE)] pub enum GeneratorState { /// The generator yielded. Yielded(Value), @@ -97,9 +98,3 @@ impl GeneratorState { } from_value!(GeneratorState, into_generator_state); - -impl Named for GeneratorState { - const BASE_NAME: RawStr = RawStr::from_str("GeneratorState"); -} - -impl InstallWith for GeneratorState {} diff --git a/crates/rune/src/runtime/hasher.rs b/crates/rune/src/runtime/hasher.rs index d0228fa77..a0f9b5aff 100644 --- a/crates/rune/src/runtime/hasher.rs +++ b/crates/rune/src/runtime/hasher.rs @@ -7,7 +7,7 @@ use crate::Any; /// The default hasher used in Rune. #[derive(Any)] -#[rune(builtin)] +#[rune(builtin, static_type = HASHER_TYPE)] pub struct Hasher { hasher: DefaultHasher, } diff --git a/crates/rune/src/runtime/iterator.rs b/crates/rune/src/runtime/iterator.rs index f44df95a7..c0603d736 100644 --- a/crates/rune/src/runtime/iterator.rs +++ b/crates/rune/src/runtime/iterator.rs @@ -5,9 +5,9 @@ use core::iter; use crate::no_std::prelude::*; use crate::no_std::vec; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{FromValue, Function, Panic, RawStr, ToValue, Value, VmErrorKind, VmResult}; +use crate as rune; +use crate::runtime::{FromValue, Function, Panic, ToValue, Value, VmErrorKind, VmResult}; +use crate::Any; // Note: A fair amount of code in this module is duplicated from the Rust // project under the MIT license. @@ -72,6 +72,8 @@ macro_rules! maybe { } /// An owning iterator. +#[derive(Any)] +#[rune(builtin, static_type = ITERATOR_TYPE, from_value = Value::into_iterator)] pub struct Iterator { iter: IterRepr, } @@ -384,14 +386,6 @@ impl fmt::Debug for Iterator { } } -impl Named for Iterator { - const BASE_NAME: RawStr = RawStr::from_str("Iterator"); -} - -impl InstallWith for Iterator {} - -from_value!(Iterator, into_iterator); - /// The inner representation of an [Iterator]. It handles all the necessary /// dynamic dispatch to support dynamic iterators. enum IterRepr { diff --git a/crates/rune/src/runtime/object.rs b/crates/rune/src/runtime/object.rs index 8918b3214..693c22f5e 100644 --- a/crates/rune/src/runtime/object.rs +++ b/crates/rune/src/runtime/object.rs @@ -9,9 +9,9 @@ use crate::no_std::collections::{btree_map, BTreeMap}; use crate::no_std::prelude::*; use crate as rune; -use crate::compile::{ItemBuf, Named}; -use crate::module::InstallWith; -use crate::runtime::{FromValue, Iterator, ProtocolCaller, RawStr, Ref, ToValue, Value, VmResult}; +use crate::compile::ItemBuf; +use crate::runtime::{FromValue, Iterator, ProtocolCaller, Ref, ToValue, Value, VmResult}; +use crate::Any; /// An owning iterator over the entries of a `Object`. /// @@ -60,9 +60,9 @@ pub type Values<'a> = btree_map::Values<'a, String, Value>; /// Struct representing a dynamic anonymous object. /// -/// # Examples +/// # Rust Examples /// -/// ``` +/// ```rust /// let mut object = rune::runtime::Object::new(); /// assert!(object.is_empty()); /// @@ -75,8 +75,9 @@ pub type Values<'a> = btree_map::Values<'a, String, Value>; /// assert_eq!(None::, object.get_value("baz").into_result()?); /// # Ok::<_, rune::Error>(()) /// ``` -#[derive(Default, Clone)] +#[derive(Any, Default, Clone)] #[repr(transparent)] +#[rune(builtin, static_type = OBJECT_TYPE)] pub struct Object { inner: BTreeMap, } @@ -463,12 +464,6 @@ impl iter::FromIterator<(String, Value)> for Object { from_value!(Object, into_object); -impl Named for Object { - const BASE_NAME: RawStr = RawStr::from_str("Object"); -} - -impl InstallWith for Object {} - pub struct DebugStruct<'a> { item: &'a ItemBuf, st: &'a Object, diff --git a/crates/rune/src/runtime/range.rs b/crates/rune/src/runtime/range.rs index 285be267b..7ceb81331 100644 --- a/crates/rune/src/runtime/range.rs +++ b/crates/rune/src/runtime/range.rs @@ -52,7 +52,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range, static_type = RANGE_TYPE)] pub struct Range { /// The start value of the range. #[rune(get, set)] @@ -317,5 +317,3 @@ where VmResult::Ok(ops::Range { start, end }) } } - -from_value!(Range, into_range); diff --git a/crates/rune/src/runtime/range_from.rs b/crates/rune/src/runtime/range_from.rs index 9686b1ebb..74b3a1f75 100644 --- a/crates/rune/src/runtime/range_from.rs +++ b/crates/rune/src/runtime/range_from.rs @@ -49,7 +49,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range_from, static_type = RANGE_FROM_TYPE)] pub struct RangeFrom { /// The start value of the range. #[rune(get, set)] @@ -285,5 +285,3 @@ where VmResult::Ok(ops::RangeFrom { start }) } } - -from_value!(RangeFrom, into_range_from); diff --git a/crates/rune/src/runtime/range_full.rs b/crates/rune/src/runtime/range_full.rs index 1abad671e..a1f6b6319 100644 --- a/crates/rune/src/runtime/range_full.rs +++ b/crates/rune/src/runtime/range_full.rs @@ -30,7 +30,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Default, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range_full, static_type = RANGE_FULL_TYPE)] pub struct RangeFull; impl RangeFull { @@ -105,5 +105,3 @@ impl FromValue for ops::RangeFull { VmResult::Ok(ops::RangeFull) } } - -from_value!(RangeFull, into_range_full); diff --git a/crates/rune/src/runtime/range_inclusive.rs b/crates/rune/src/runtime/range_inclusive.rs index ea4187f96..b4da9f62f 100644 --- a/crates/rune/src/runtime/range_inclusive.rs +++ b/crates/rune/src/runtime/range_inclusive.rs @@ -53,7 +53,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range_inclusive, static_type = RANGE_INCLUSIVE_TYPE)] pub struct RangeInclusive { /// The start value of the range. #[rune(get, set)] @@ -318,5 +318,3 @@ where VmResult::Ok(start..=end) } } - -from_value!(RangeInclusive, into_range_inclusive); diff --git a/crates/rune/src/runtime/range_to.rs b/crates/rune/src/runtime/range_to.rs index a36100411..337774e5e 100644 --- a/crates/rune/src/runtime/range_to.rs +++ b/crates/rune/src/runtime/range_to.rs @@ -39,7 +39,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range_to, static_type = RANGE_TO_TYPE)] pub struct RangeTo { /// The end value of the range. #[rune(get, set)] @@ -206,5 +206,3 @@ where VmResult::Ok(ops::RangeTo { end }) } } - -from_value!(RangeTo, into_range_to); diff --git a/crates/rune/src/runtime/range_to_inclusive.rs b/crates/rune/src/runtime/range_to_inclusive.rs index 71acbb9d3..654af1914 100644 --- a/crates/rune/src/runtime/range_to_inclusive.rs +++ b/crates/rune/src/runtime/range_to_inclusive.rs @@ -39,7 +39,7 @@ use crate::Any; /// # Ok::<_, rune::Error>(()) /// ``` #[derive(Any, Clone)] -#[rune(builtin, constructor)] +#[rune(builtin, constructor, from_value = Value::into_range_to_inclusive, static_type = RANGE_TO_INCLUSIVE_TYPE)] pub struct RangeToInclusive { /// The end value of the range. #[rune(get, set)] @@ -206,5 +206,3 @@ where VmResult::Ok(ops::RangeToInclusive { end }) } } - -from_value!(RangeToInclusive, into_range_to_inclusive); diff --git a/crates/rune/src/runtime/static_type.rs b/crates/rune/src/runtime/static_type.rs index 9f60341c6..30b90a259 100644 --- a/crates/rune/src/runtime/static_type.rs +++ b/crates/rune/src/runtime/static_type.rs @@ -114,7 +114,6 @@ pub(crate) static BYTES_TYPE: &StaticType = &StaticType { hash: ::rune_macros::hash!(::std::bytes::Bytes), }; -impl_static_type!(rt::Bytes => BYTES_TYPE); impl_static_type!([u8] => BYTES_TYPE); pub(crate) static VEC_TYPE: &StaticType = &StaticType { @@ -122,9 +121,8 @@ pub(crate) static VEC_TYPE: &StaticType = &StaticType { hash: ::rune_macros::hash!(::std::vec::Vec), }; -impl_static_type!(rt::Vec => VEC_TYPE); -impl_static_type!(impl vec::Vec => VEC_TYPE); impl_static_type!([rt::Value] => VEC_TYPE); +impl_static_type!(impl vec::Vec => VEC_TYPE); impl_static_type!(impl rt::VecTuple => VEC_TYPE); pub(crate) static TUPLE_TYPE: &StaticType = &StaticType { @@ -133,64 +131,50 @@ pub(crate) static TUPLE_TYPE: &StaticType = &StaticType { }; impl_static_type!(rt::OwnedTuple => TUPLE_TYPE); -impl_static_type!(rt::Tuple => TUPLE_TYPE); pub(crate) static OBJECT_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Object"), hash: ::rune_macros::hash!(::std::object::Object), }; -impl_static_type!(rt::Object => OBJECT_TYPE); impl_static_type!(rt::Struct => OBJECT_TYPE); +impl_static_type!(impl HashMap => OBJECT_TYPE); pub(crate) static RANGE_FROM_TYPE: &StaticType = &StaticType { name: RawStr::from_str("RangeFrom"), hash: ::rune_macros::hash!(::std::ops::RangeFrom), }; -impl_static_type!(rt::RangeFrom => RANGE_FROM_TYPE); - pub(crate) static RANGE_FULL_TYPE: &StaticType = &StaticType { name: RawStr::from_str("RangeFull"), hash: ::rune_macros::hash!(::std::ops::RangeFull), }; -impl_static_type!(rt::RangeFull => RANGE_FULL_TYPE); - pub(crate) static RANGE_INCLUSIVE_TYPE: &StaticType = &StaticType { name: RawStr::from_str("RangeInclusive"), hash: ::rune_macros::hash!(::std::ops::RangeInclusive), }; -impl_static_type!(rt::RangeInclusive => RANGE_INCLUSIVE_TYPE); - pub(crate) static RANGE_TO_INCLUSIVE_TYPE: &StaticType = &StaticType { name: RawStr::from_str("RangeToInclusive"), hash: ::rune_macros::hash!(::std::ops::RangeToInclusive), }; -impl_static_type!(rt::RangeToInclusive => RANGE_TO_INCLUSIVE_TYPE); - pub(crate) static RANGE_TO_TYPE: &StaticType = &StaticType { name: RawStr::from_str("RangeTo"), hash: ::rune_macros::hash!(::std::ops::RangeTo), }; -impl_static_type!(rt::RangeTo => RANGE_TO_TYPE); - pub(crate) static RANGE_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Range"), hash: ::rune_macros::hash!(::std::ops::Range), }; -impl_static_type!(rt::Range => RANGE_TYPE); - pub(crate) static CONTROL_FLOW_TYPE: &StaticType = &StaticType { name: RawStr::from_str("ControlFlow"), hash: ::rune_macros::hash!(::std::ops::ControlFlow), }; -impl_static_type!(rt::ControlFlow => CONTROL_FLOW_TYPE); impl_static_type!(impl ControlFlow => CONTROL_FLOW_TYPE); pub(crate) static FUTURE_TYPE: &StaticType = &StaticType { @@ -198,29 +182,21 @@ pub(crate) static FUTURE_TYPE: &StaticType = &StaticType { hash: ::rune_macros::hash!(::std::future::Future), }; -impl_static_type!(rt::Future => FUTURE_TYPE); - pub(crate) static GENERATOR_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Generator"), hash: ::rune_macros::hash!(::std::ops::Generator), }; -impl_static_type!(rt::Generator => GENERATOR_TYPE); - pub(crate) static GENERATOR_STATE_TYPE: &StaticType = &StaticType { name: RawStr::from_str("GeneratorState"), hash: ::rune_macros::hash!(::std::ops::GeneratorState), }; -impl_static_type!(rt::GeneratorState => GENERATOR_STATE_TYPE); - pub(crate) static STREAM_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Stream"), hash: ::rune_macros::hash!(::std::stream::Stream), }; -impl_static_type!(rt::Stream => STREAM_TYPE); - pub(crate) static RESULT_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Result"), hash: ::rune_macros::hash!(::std::result::Result), @@ -240,40 +216,31 @@ pub(crate) static FUNCTION_TYPE: &StaticType = &StaticType { hash: ::rune_macros::hash!(::std::ops::Function), }; -impl_static_type!(rt::Function => FUNCTION_TYPE); -impl_static_type!(impl HashMap => OBJECT_TYPE); - pub(crate) static FORMAT_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Format"), hash: ::rune_macros::hash!(::std::fmt::Format), }; -impl_static_type!(rt::Format => FORMAT_TYPE); - pub(crate) static ITERATOR_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Iterator"), hash: ::rune_macros::hash!(::std::iter::Iterator), }; -impl_static_type!(rt::Iterator => ITERATOR_TYPE); - -pub(crate) static TYPE: &StaticType = &StaticType { - name: RawStr::from_str("Type"), - hash: ::rune_macros::hash!(::std::any::Type), -}; - -impl_static_type!(rt::Type => TYPE); - -pub(crate) static ORDERING: &StaticType = &StaticType { +pub(crate) static ORDERING_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Ordering"), hash: ::rune_macros::hash!(::std::cmp::Ordering), }; -impl_static_type!(Ordering => ORDERING); +impl_static_type!(Ordering => ORDERING_TYPE); -pub(crate) static HASHER: &StaticType = &StaticType { +pub(crate) static HASHER_TYPE: &StaticType = &StaticType { name: RawStr::from_str("Hasher"), hash: ::rune_macros::hash!(::std::hash::Hasher), }; -impl_static_type!(rt::Hasher => HASHER); +pub(crate) static TYPE: &StaticType = &StaticType { + name: RawStr::from_str("Type"), + hash: ::rune_macros::hash!(::std::any::Type), +}; + +impl_static_type!(rt::Type => TYPE); diff --git a/crates/rune/src/runtime/stream.rs b/crates/rune/src/runtime/stream.rs index 4c5f33c93..f8c8787a8 100644 --- a/crates/rune/src/runtime/stream.rs +++ b/crates/rune/src/runtime/stream.rs @@ -1,12 +1,12 @@ use core::fmt; -use crate::compile::Named; -use crate::module::InstallWith; -use crate::runtime::{ - GeneratorState, RawStr, Shared, Value, Vm, VmErrorKind, VmExecution, VmResult, -}; +use crate as rune; +use crate::runtime::{GeneratorState, Shared, Value, Vm, VmErrorKind, VmExecution, VmResult}; +use crate::Any; /// A stream with a stored virtual machine. +#[derive(Any)] +#[rune(builtin, static_type = STREAM_TYPE, from_value = Value::into_stream, from_value_params = [Vm])] pub struct Stream where T: AsRef + AsMut, @@ -81,15 +81,6 @@ impl Stream<&mut Vm> { } } -impl Named for Stream -where - T: AsRef + AsMut, -{ - const BASE_NAME: RawStr = RawStr::from_str("Stream"); -} - -impl InstallWith for Stream where T: AsRef + AsMut {} - impl fmt::Debug for Stream where T: AsRef + AsMut, @@ -100,5 +91,3 @@ where .finish() } } - -from_value!(Stream, into_stream); diff --git a/crates/rune/src/runtime/tuple.rs b/crates/rune/src/runtime/tuple.rs index b5ff2301f..424a47bee 100644 --- a/crates/rune/src/runtime/tuple.rs +++ b/crates/rune/src/runtime/tuple.rs @@ -4,14 +4,16 @@ use core::slice; use crate::no_std::prelude::*; -use crate::compile::Named; -use crate::module::InstallWith; +use crate as rune; use crate::runtime::{ - ConstValue, FromValue, Mut, RawMut, RawRef, RawStr, Ref, Shared, ToValue, UnsafeToMut, - UnsafeToRef, Value, VmErrorKind, VmResult, + ConstValue, FromValue, Mut, RawMut, RawRef, Ref, Shared, ToValue, UnsafeToMut, UnsafeToRef, + Value, VmErrorKind, VmResult, }; +use crate::Any; /// The type of a tuple slice. +#[derive(Any)] +#[rune(builtin, static_type = TUPLE_TYPE)] #[repr(transparent)] pub struct Tuple { values: [Value], @@ -80,12 +82,6 @@ impl<'a> IntoIterator for &'a mut Tuple { } } -impl Named for Tuple { - const BASE_NAME: RawStr = RawStr::from_str("Tuple"); -} - -impl InstallWith for Tuple {} - /// Struct representing a dynamic anonymous object. /// /// To access borrowed values of a tuple in native functions, use [`Tuple`]. diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index 187674f30..a47ae580f 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -1100,7 +1100,7 @@ impl Value { Self::Integer(..) => crate::runtime::static_type::INTEGER_TYPE.hash, Self::Float(..) => crate::runtime::static_type::FLOAT_TYPE.hash, Self::Type(..) => crate::runtime::static_type::TYPE.hash, - Self::Ordering(..) => crate::runtime::static_type::ORDERING.hash, + Self::Ordering(..) => crate::runtime::static_type::ORDERING_TYPE.hash, Self::String(..) => crate::runtime::static_type::STRING_TYPE.hash, Self::Bytes(..) => crate::runtime::static_type::BYTES_TYPE.hash, Self::Vec(..) => crate::runtime::static_type::VEC_TYPE.hash, @@ -1140,7 +1140,7 @@ impl Value { Self::Integer(..) => TypeInfo::StaticType(crate::runtime::static_type::INTEGER_TYPE), Self::Float(..) => TypeInfo::StaticType(crate::runtime::static_type::FLOAT_TYPE), Self::Type(..) => TypeInfo::StaticType(crate::runtime::static_type::TYPE), - Self::Ordering(..) => TypeInfo::StaticType(crate::runtime::static_type::ORDERING), + Self::Ordering(..) => TypeInfo::StaticType(crate::runtime::static_type::ORDERING_TYPE), Self::String(..) => TypeInfo::StaticType(crate::runtime::static_type::STRING_TYPE), Self::Bytes(..) => TypeInfo::StaticType(crate::runtime::static_type::BYTES_TYPE), Self::Vec(..) => TypeInfo::StaticType(crate::runtime::static_type::VEC_TYPE), @@ -1361,7 +1361,7 @@ impl Value { } let zero = *value == 0.0; - hasher.write_f64(f64::from(zero) * 0.0 + f64::from(!zero) * *value); + hasher.write_f64((zero as u8 as f64) * 0.0 + (!zero as u8 as f64) * *value); return VmResult::Ok(()); } Value::String(string) => { diff --git a/crates/rune/src/runtime/vec.rs b/crates/rune/src/runtime/vec.rs index 2ddd72bf4..0c2dcd0ba 100644 --- a/crates/rune/src/runtime/vec.rs +++ b/crates/rune/src/runtime/vec.rs @@ -10,12 +10,12 @@ use core::slice::SliceIndex; use crate::no_std::prelude::*; use crate::no_std::vec; -use crate::compile::Named; -use crate::module::InstallWith; +use crate as rune; use crate::runtime::{ - Formatter, FromValue, Iterator, ProtocolCaller, RawRef, RawStr, Ref, Shared, ToValue, - UnsafeToRef, Value, VmErrorKind, VmResult, + Formatter, FromValue, Iterator, ProtocolCaller, RawRef, Ref, Shared, ToValue, UnsafeToRef, + Value, VmErrorKind, VmResult, }; +use crate::Any; use self::iter::Iter; @@ -36,8 +36,9 @@ use self::iter::Iter; /// assert_eq!(None::, vec.get_value(2).into_result()?); /// # Ok::<_, rune::Error>(()) /// ``` -#[derive(Clone)] +#[derive(Clone, Any)] #[repr(transparent)] +#[rune(builtin, static_type = VEC_TYPE, from_value = Value::into_vec)] pub struct Vec { inner: vec::Vec, } @@ -448,14 +449,6 @@ impl From> for Vec { } } -impl Named for Vec { - const BASE_NAME: RawStr = RawStr::from_str("Vec"); -} - -impl InstallWith for Vec {} - -from_value!(Vec, into_vec); - impl FromValue for vec::Vec where T: FromValue,