rune/lib.rs
1//! <img alt="rune logo" src="https://raw.githubusercontent.com/rune-rs/rune/main/assets/icon.png" />
2//! <br>
3//! <a href="https://github.com/rune-rs/rune"><img alt="github" src="https://img.shields.io/badge/github-rune--rs/rune-8da0cb?style=for-the-badge&logo=github" height="20"></a>
4//! <a href="https://crates.io/crates/rune"><img alt="crates.io" src="https://img.shields.io/crates/v/rune.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20"></a>
5//! <a href="https://docs.rs/rune"><img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-rune-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20"></a>
6//! <a href="https://discord.gg/v5AeNkT"><img alt="chat on discord" src="https://img.shields.io/discord/558644981137670144.svg?logo=discord&style=flat-square" height="20"></a>
7//! <br>
8//! Minimum support: Rust <b>1.92+</b>.
9//! <br>
10//! <br>
11//! <a href="https://rune-rs.github.io"><b>Visit the site 🌐</b></a>
12//! —
13//! <a href="https://rune-rs.github.io/book/"><b>Read the book 📖</b></a>
14//! <br>
15//! <br>
16//!
17//! The Rune Language, an embeddable dynamic programming language for Rust.
18//!
19//! <br>
20//!
21//! ## Contributing
22//!
23//! If you want to help out, please have a look at [Open Issues].
24//!
25//! <br>
26//!
27//! ## Highlights of Rune
28//!
29//! * Run simple [Scripts 📖][support-scripts].
30//! * Runs a compact representation of the language on top of an efficient
31//! [stack-based virtual machine][support-virtual-machine].
32//! * Clean [Rust integration 💻][support-rust-integration].
33//! * [Multithreaded 📖][support-multithreading] execution.
34//! * [Hot reloading 📖][support-hot-reloading].
35//! * Memory safe through [reference counting 📖][support-reference-counted].
36//! * [Awesome macros 📖][support-macros] and [Template literals 📖][support-templates].
37//! * [Try operators 📖][support-try] and [Pattern matching 📖][support-patterns].
38//! * [Structs and enums 📖][support-structs] with associated data and
39//! functions.
40//! * Dynamic containers like [vectors 📖][support-dynamic-vectors], [objects
41//! 📖][support-anon-objects], and [tuples 📖][support-anon-tuples] all with
42//! out-of-the-box [serde support 💻][support-serde].
43//! * First-class [async support 📖][support-async] with [Generators 📖][support-generators].
44//! * Dynamic [instance functions 📖][support-instance-functions].
45//! * [Stack isolation 📖][support-stack-isolation] between function calls.
46//!
47//! <br>
48//!
49//! ## Rune scripts
50//!
51//! You can run Rune programs with the bundled CLI:
52//!
53//! ```text
54//! cargo run --bin rune -- run scripts/hello_world.rn
55//! ```
56//!
57//! If you want to see detailed diagnostics of your program while it's running,
58//! you can use:
59//!
60//! ```text
61//! cargo run --bin rune -- run scripts/hello_world.rn --dump --trace
62//! ```
63//!
64//! See `--help` for more information.
65//!
66//! <br>
67//!
68//! ## Running scripts from Rust
69//!
70//! > You can find more examples [in the `examples` folder].
71//!
72//! The following is a complete example, including rich diagnostics using
73//! [`termcolor`]. It can be made much simpler if this is not needed.
74//!
75//! [`termcolor`]: https://docs.rs/termcolor
76//!
77//! ```no_run
78//! use rune::{Context, Diagnostics, Source, Sources, Vm};
79//! use rune::termcolor::{ColorChoice, StandardStream};
80//! use rune::sync::Arc;
81//!
82//! let context = Context::with_default_modules()?;
83//!
84//! let mut sources = Sources::new();
85//! sources.insert(Source::memory("pub fn add(a, b) { a + b }")?);
86//!
87//! let mut diagnostics = Diagnostics::new();
88//!
89//! let result = rune::prepare(&mut sources)
90//! .with_context(&context)
91//! .with_diagnostics(&mut diagnostics)
92//! .build_vm();
93//!
94//! if !diagnostics.is_empty() {
95//! let mut writer = StandardStream::stderr(ColorChoice::Always);
96//! diagnostics.emit(&mut writer, &sources)?;
97//! }
98//!
99//! let mut vm = result?;
100//!
101//! let output = vm.call(["add"], (10i64, 20i64))?;
102//! let output: i64 = rune::from_value(output)?;
103//!
104//! println!("{}", output);
105//! # Ok::<_, rune::support::Error>(())
106//! ```
107//!
108//! [in the `examples` folder]: https://github.com/rune-rs/rune/tree/main/examples/examples
109//! [Open Issues]: https://github.com/rune-rs/rune/issues
110//! [support-anon-objects]: https://rune-rs.github.io/book/objects.html
111//! [support-anon-tuples]: https://rune-rs.github.io/book/tuples.html
112//! [support-async]: https://rune-rs.github.io/book/async.html
113//! [support-dynamic-vectors]: https://rune-rs.github.io/book/vectors.html
114//! [support-generators]: https://rune-rs.github.io/book/generators.html
115//! [support-hot-reloading]: https://rune-rs.github.io/book/hot_reloading.html
116//! [support-instance-functions]: https://rune-rs.github.io/book/instance_functions.html
117//! [support-macros]: https://rune-rs.github.io/book/macros.html
118//! [support-multithreading]: https://rune-rs.github.io/book/multithreading.html
119//! [support-patterns]: https://rune-rs.github.io/book/pattern_matching.html
120//! [support-reference-counted]: https://rune-rs.github.io/book/variables.html
121//! [support-rust-integration]: https://github.com/rune-rs/rune/tree/main/crates/rune-modules
122//! [support-scripts]: https://rune-rs.github.io/book/scripts.html
123//! [support-serde]: https://github.com/rune-rs/rune/blob/main/crates/rune-modules/src/json.rs
124//! [support-stack-isolation]: https://rune-rs.github.io/book/call_frames.html
125//! [support-structs]: https://rune-rs.github.io/book/structs.html
126//! [support-templates]: https://rune-rs.github.io/book/template_literals.html
127//! [support-try]: https://rune-rs.github.io/book/try_operator.html
128//! [support-virtual-machine]: https://rune-rs.github.io/book/the_stack.html
129
130#![allow(clippy::branches_sharing_code)]
131#![allow(clippy::enum_variant_names)]
132#![allow(clippy::match_like_matches_macro)]
133#![allow(clippy::module_inception)]
134#![allow(clippy::needless_doctest_main)]
135#![allow(clippy::self_named_constructors)]
136#![allow(clippy::should_implement_trait)]
137#![allow(clippy::too_many_arguments)]
138#![allow(clippy::type_complexity)]
139#![cfg_attr(rune_docsrs, feature(doc_cfg))]
140#![cfg_attr(rune_nightly, deny(rustdoc::missing_doc_code_examples))]
141#![cfg_attr(rune_nightly, feature(rustdoc_missing_doc_code_examples))]
142#![deny(missing_docs)]
143#![deny(rustdoc::broken_intra_doc_links)]
144#![deny(rustdoc::private_doc_tests)]
145#![no_std]
146
147#[cfg(feature = "std")]
148#[macro_use]
149extern crate std;
150
151// This is here for forward compatibility when we can support allocation-free
152// execution.
153#[cfg(not(feature = "alloc"))]
154compile_error!("The `alloc` feature is currently required to build rune, but will change for parts of rune in the future.");
155
156#[macro_use]
157extern crate alloc as rust_alloc;
158
159/// A macro that can be used to construct a [Span][crate::ast::Span] that can be
160/// pattern matched over.
161///
162/// # Examples
163///
164/// ```
165/// use rune::ast::Span;
166/// use rune::span;
167///
168/// let span = Span::new(42, 84);
169/// assert!(matches!(span, span!(42, 84)));
170/// ```
171#[macro_export]
172#[doc(hidden)]
173macro_rules! span {
174 ($start:expr, $end:expr) => {
175 $crate::ast::Span {
176 start: $crate::ast::ByteIndex($start),
177 end: $crate::ast::ByteIndex($end),
178 }
179 };
180}
181
182pub mod alloc;
183#[doc(inline)]
184pub use rune_alloc::sync;
185
186/// Helper prelude for `#[no_std]` support.
187pub mod no_std;
188
189#[macro_use]
190mod internal_macros;
191pub(crate) use self::internal_macros::{async_vm_try, declare_dyn_fn, declare_dyn_trait, vm_error};
192
193mod exported_macros;
194#[doc(inline)]
195#[allow(deprecated)]
196pub use self::exported_macros::{docstring, nested_try, vm_panic, vm_try, vm_write};
197
198#[macro_use]
199pub mod ast;
200
201#[cfg(feature = "fmt")]
202#[cfg_attr(rune_docsrs, doc(cfg(feature = "fmt")))]
203pub mod fmt;
204
205#[cfg(feature = "emit")]
206#[cfg_attr(rune_docsrs, doc(cfg(feature = "emit")))]
207#[doc(inline)]
208pub use ::codespan_reporting::term::termcolor;
209
210pub(crate) mod any;
211#[doc(inline)]
212pub use self::any::Any;
213
214mod build;
215pub use self::build::{prepare, Build, BuildError};
216
217pub mod compile;
218#[doc(inline)]
219pub use self::compile::{Context, ContextError, Options};
220
221pub mod item;
222#[doc(inline)]
223pub use self::item::{Item, ItemBuf};
224
225#[doc(hidden)]
226mod function_meta;
227
228mod function;
229
230pub mod module;
231#[doc(inline)]
232pub use self::module::module::Module;
233
234pub mod diagnostics;
235#[doc(inline)]
236pub use self::diagnostics::Diagnostics;
237
238pub mod hash;
239#[doc(inline)]
240pub use self::hash::{Hash, NonZeroHash, ToTypeHash};
241
242mod hashbrown;
243
244mod params;
245pub use self::params::Params;
246
247mod hir;
248
249mod indexing;
250
251pub mod macros;
252
253pub mod modules;
254
255pub mod parse;
256
257pub(crate) mod grammar;
258
259pub mod query;
260
261pub mod runtime;
262#[doc(inline)]
263pub use self::runtime::{
264 from_const_value, from_value, to_const_value, to_value, FromConstValue, FromValue, Mut, Ref,
265 ToConstValue, ToValue, TypeHash, Unit, Value, Vm, VmError,
266};
267
268mod shared;
269
270pub mod source;
271#[doc(inline)]
272pub use self::source::Source;
273
274#[macro_use]
275mod sources;
276#[doc(inline)]
277pub use self::sources::{SourceId, Sources};
278
279mod worker;
280
281#[doc(hidden)]
282pub mod support;
283
284#[cfg(feature = "workspace")]
285#[cfg_attr(rune_docsrs, doc(cfg(feature = "workspace")))]
286pub mod workspace;
287
288/// Macro used to annotate native functions which can be loaded as attribute
289/// macros in rune.
290///
291/// See [`Module::macro_meta`][crate::Module::macro_meta].
292///
293/// # Examples
294///
295/// ```
296/// use rune::Module;
297/// use rune::ast;
298/// use rune::compile;
299/// use rune::macros::{quote, MacroContext, TokenStream};
300/// use rune::parse::Parser;
301/// use rune::alloc::prelude::*;
302///
303/// /// Takes an identifier and converts it into a string.
304/// ///
305/// /// # Examples
306/// ///
307/// /// ```rune
308/// /// assert_eq!(ident_to_string!(Hello), "Hello");
309/// /// ```
310/// #[rune::macro_]
311/// fn ident_to_string(cx: &mut MacroContext<'_, '_, '_>, stream: &TokenStream) -> compile::Result<TokenStream> {
312/// let mut p = Parser::from_token_stream(stream, cx.input_span());
313/// let ident = p.parse_all::<ast::Ident>()?;
314/// let ident = cx.resolve(ident)?.try_to_owned()?;
315/// let string = cx.lit(&ident)?;
316/// Ok(quote!(#string).into_token_stream(cx)?)
317/// }
318///
319/// let mut m = Module::new();
320/// m.macro_meta(ident_to_string)?;
321/// # Ok::<_, rune::support::Error>(())
322/// ```
323#[doc(inline)]
324pub use rune_macros::attribute_macro;
325
326/// Macro used to annotate native functions which can be loaded into rune.
327///
328/// This macro automatically performs the following things:
329/// * Rust documentation comments are captured so that it can be used in
330/// generated Rune documentation.
331/// * The name of arguments is captured to improve documentation generation.
332/// * If an instance function is annotated this is detected (if the function
333/// receives `self`). This behavior can be forced using
334/// `#[rune::function(instance)]` if the function doesn't take `self`.
335/// * The name of the function can be set using the `#[rune::function(path =
336/// name)]` argument.
337/// * An associated function can be specified with the `#[rune::function(path =
338/// Type::name)]` argument. If `instance` is specified it is an associated
339/// instance function that can be defined externally.
340/// * Instance functions can be made a protocol function
341/// `#[rune::function(protocol = DISPLAY_FMT)]`.
342///
343/// # Instance and associated functions
344///
345/// Instance and associated functions are a bit tricky to declare using
346/// `#[rune::function]`, and care must be taken that you understand what needs
347/// to be done. So this section is dedicated to documenting the ins and outs of
348/// the process.
349///
350/// Briefly we should mention that instance functions are functions which are
351/// associated with a type at runtime. Calling a value like `value.hello()`
352/// invokes the `hello` associated function through the instance of `value`. The
353/// exact type of `value` will then be used to look up which function to call.
354/// They must take some kind of `self` parameter. Meanwhile associated functions
355/// are just functions which are associated with a static type. Like
356/// `String::new()`. The type `String` must then be in scope, and the function
357/// does not take a `self` parameter.
358///
359/// This is how you declare an instance function which takes `&self` or `&mut
360/// self`:
361///
362/// ```rust
363/// # use rune::Any;
364/// #[derive(Any)]
365/// struct Struct {
366/// /* .. */
367/// }
368///
369/// impl Struct {
370/// /// Get the length of the `Struct`.
371/// #[rune::function]
372/// fn len(&self) -> usize {
373/// /* .. */
374/// # todo!()
375/// }
376/// }
377/// ```
378///
379/// If a function does not take `&self` or `&mut self`, you must specify that
380/// it's an instance function using `#[rune::function(instance)]`. The first
381/// argument is then considered the instance the function gets associated with:
382///
383/// ```rust
384/// # use rune::Any;
385/// #[derive(Any)]
386/// struct Struct {
387/// /* .. */
388/// }
389///
390/// /// Get the length of the `Struct`.
391/// #[rune::function(instance)]
392/// fn len(this: &Struct) -> usize {
393/// /* .. */
394/// # todo!()
395/// }
396/// ```
397///
398/// To declare an associated function which does not receive the type we
399/// must specify the path to the function using `#[rune::function(path =
400/// Self::<name>)]`:
401///
402/// ```rust
403/// # use rune::Any;
404/// #[derive(Any)]
405/// struct Struct {
406/// /* .. */
407/// }
408///
409/// impl Struct {
410/// /// Construct a new [`Struct`].
411/// #[rune::function(path = Self::new)]
412/// fn new() -> Struct {
413/// Struct {
414/// /* .. */
415/// }
416/// }
417/// }
418/// ```
419///
420/// Or externally like this:
421///
422/// ```rust
423/// # use rune::Any;
424/// #[derive(Any)]
425/// struct Struct {
426/// /* .. */
427/// }
428///
429/// /// Construct a new [`Struct`].
430/// #[rune::function(free, path = Struct::new)]
431/// fn new() -> Struct {
432/// Struct {
433/// /* .. */
434/// }
435/// }
436/// ```
437///
438/// The first part `Struct` in `Struct::new` is used to determine the type
439/// the function is associated with.
440///
441/// Protocol functions can either be defined in an impl block or externally. To
442/// define a protocol externally, you can simply do this:
443///
444/// ```rust
445/// use rune::Any;
446/// use rune::runtime::Formatter;
447/// use rune::alloc::fmt::TryWrite;
448/// use rune::alloc;
449///
450/// #[derive(Any)]
451/// struct Struct {
452/// /* .. */
453/// }
454///
455/// #[rune::function(instance, protocol = DISPLAY_FMT)]
456/// fn display_fmt(this: &Struct, f: &mut Formatter) -> alloc::Result<()> {
457/// write!(f, "Struct {{ /* .. */ }}")
458/// }
459/// ```
460///
461/// # Examples
462///
463/// Defining and using a simple free function:
464///
465/// ```
466/// use rune::{Module, ContextError};
467///
468/// /// This is a pretty neat function which is called `std::str::to_uppercase("hello")`.
469/// #[rune::function]
470/// fn to_uppercase(string: &str) -> String {
471/// string.to_uppercase()
472/// }
473///
474/// fn module() -> Result<Module, ContextError> {
475/// let mut m = Module::new();
476/// m.function_meta(to_uppercase)?;
477/// Ok(m)
478/// }
479/// ```
480///
481/// A free instance function:
482///
483/// ```
484/// use rune::{Module, ContextError};
485///
486/// /// This is a pretty neat function, which is called like `"hello".to_uppercase()`.
487/// #[rune::function(instance)]
488/// fn to_uppercase(string: &str) -> String {
489/// string.to_uppercase()
490/// }
491///
492/// /// This is a pretty neat function, which is called like `string::to_uppercase2("hello")`.
493/// #[rune::function(path = string)]
494/// fn to_uppercase2(string: &str) -> String {
495/// string.to_uppercase()
496/// }
497///
498/// fn module() -> Result<Module, ContextError> {
499/// let mut m = Module::new();
500/// m.function_meta(to_uppercase)?;
501/// m.function_meta(to_uppercase2)?;
502/// Ok(m)
503/// }
504/// ```
505///
506/// Regular instance and protocol functions:
507///
508/// ```
509/// use rune::{Any, Module, ContextError};
510/// use rune::runtime::Formatter;
511/// use rune::alloc::fmt::TryWrite;
512/// use rune::alloc;
513///
514/// #[derive(Any)]
515/// struct String {
516/// inner: std::string::String
517/// }
518///
519/// impl String {
520/// /// Construct a new string wrapper.
521/// #[rune::function(path = Self::new)]
522/// fn new(string: &str) -> Self {
523/// Self {
524/// inner: string.into()
525/// }
526/// }
527///
528/// /// Uppercase the string inside of the string wrapper.
529/// ///
530/// /// # Examples
531/// ///
532/// /// ```rune
533/// /// let string = String::new("hello");
534/// /// assert_eq!(string.to_uppercase(), "HELLO");
535/// /// ```
536/// #[rune::function]
537/// fn to_uppercase(&self) -> String {
538/// String {
539/// inner: self.inner.to_uppercase()
540/// }
541/// }
542///
543/// /// Display the string using the [`DISPLAY_FMT`] protocol.
544/// ///
545/// /// # Examples
546/// ///
547/// /// ```rune
548/// /// let string = String::new("hello");
549/// /// assert_eq!(format!("{}", string), "hello");
550/// /// ```
551/// #[rune::function(protocol = DISPLAY_FMT)]
552/// fn display(&self, f: &mut Formatter) -> alloc::Result<()> {
553/// write!(f, "{}", self.inner)
554/// }
555/// }
556///
557/// /// Construct a new empty string.
558/// ///
559/// /// # Examples
560/// ///
561/// /// ```rune
562/// /// let string = String::empty();
563/// /// assert_eq!(string, "hello");
564/// /// ```
565/// #[rune::function(free, path = String::empty)]
566/// fn empty() -> String {
567/// String {
568/// inner: std::string::String::new()
569/// }
570/// }
571///
572/// /// Lowercase the string inside of the string wrapper.
573/// ///
574/// /// # Examples
575/// ///
576/// /// ```rune
577/// /// let string = String::new("Hello");
578/// /// assert_eq!(string.to_lowercase(), "hello");
579/// /// ```
580/// #[rune::function(instance)]
581/// fn to_lowercase(this: &String) -> String {
582/// String {
583/// inner: this.inner.to_lowercase()
584/// }
585/// }
586///
587/// fn module() -> Result<Module, ContextError> {
588/// let mut m = Module::new();
589/// m.ty::<String>()?;
590/// m.function_meta(String::new)?;
591/// m.function_meta(empty)?;
592/// m.function_meta(String::to_uppercase)?;
593/// m.function_meta(to_lowercase)?;
594/// m.function_meta(String::display)?;
595/// Ok(m)
596/// }
597/// ```
598///
599/// # Using `vm_result` and `<expr>.vm?`.
600///
601/// > **Deprecated:** This feature will be removed in a future version of Rune.
602/// > It is not recommended that you use a `Result<T, VmError>` return type
603/// > directly and make use of helpers like [`nested_try!`] for propagating
604/// > inner errors.
605///
606/// In order to conveniently deal with virtual machine errors which require use
607/// [`VmResult`] this attribute macro supports the `vm_result` option.
608///
609/// This changes the return value of the function to be [`VmResult`], and
610/// ensures that any try operator use is wrapped as appropriate. The special
611/// operator `<expr>.vm?` is also supported in this context, which is a
612/// shorthand for the [`vm_try!`] macro.
613///
614/// ```
615/// use rune::alloc::String;
616/// use rune::alloc::prelude::*;
617///
618/// #[rune::function(vm_result)]
619/// fn trim(string: &str) -> String {
620/// string.trim().try_to_owned().vm?
621/// }
622/// ```
623///
624/// This can be combined with regular uses of the try operator `?`:
625///
626/// ```
627/// use core::str::Utf8Error;
628///
629/// use rune::alloc::String;
630/// use rune::alloc::prelude::*;
631///
632/// #[rune::function(vm_result)]
633/// fn trim_bytes(bytes: &[u8]) -> Result<String, Utf8Error> {
634/// Ok(core::str::from_utf8(bytes)?.trim().try_to_owned().vm?)
635/// }
636/// ```
637///
638/// # Using `keep` to keep the name
639///
640/// By default, the name of the function is mangled and the metadata is given
641/// the original name. This means you can't easily call the function from both
642/// Rune and Rust. This behaviour can be changed by using the `keep` attribute, in
643/// which case you must refer to the meta object by a mangled name
644/// (specifically the function name with `__meta` appended):
645///
646/// ```
647/// use rune::{Module, ContextError};
648///
649/// /// Don't mangle the name of the function
650/// #[rune::function(keep)]
651/// fn to_uppercase(string: &str) -> String {
652/// string.to_uppercase()
653/// }
654///
655/// fn module() -> Result<Module, ContextError> {
656/// let mut m = Module::new();
657/// m.function_meta(to_uppercase__meta)?;
658/// Ok(m)
659/// }
660///
661/// fn call_from_rust() {
662/// assert_eq!(to_uppercase("hello"), "HELLO");
663/// }
664/// ```
665///
666/// [`vm_try!`]: crate::vm_try
667/// [`VmResult`]: crate::runtime::VmResult
668/// [`nested_try!`]: crate::nested_try
669#[doc(inline)]
670pub use rune_macros::function;
671
672/// Calculate a type hash at compile time.
673///
674/// By default this uses the `rune` crate.
675///
676/// # Examples
677///
678/// ```
679/// use rune::Hash;
680///
681/// let hash: Hash = rune::hash!(::std::option::Option::Some);
682/// ```
683#[doc(inline)]
684pub use rune_macros::hash;
685
686/// Calculate a type hash at compile time using a custom crate.
687///
688/// By default the [`hash!`] macro uses the `rune` crate.
689///
690/// # Examples
691///
692/// ```
693/// use rune_core::hash::Hash;
694///
695/// let hash: Hash = rune::hash_in!(rune_core::hash, ::std::option::Option::Some);
696/// ```
697#[doc(inline)]
698pub use rune_macros::hash_in;
699
700/// Construct an [`Item`] reference at compile time.
701///
702/// # Examples
703///
704/// ```
705/// use rune::{Item, ItemBuf};
706///
707/// static ITEM: &Item = rune::item!(::std::ops::generator::Generator);
708///
709/// let mut item = ItemBuf::with_crate("std")?;
710/// item.push("ops")?;
711/// item.push("generator")?;
712/// item.push("Generator")?;
713///
714/// assert_eq!(item, ITEM);
715/// # Ok::<_, rune::alloc::Error>(())
716/// ```
717#[doc(inline)]
718pub use rune_macros::item;
719
720/// Construct an [`Item`] reference at compile time.
721///
722/// This variant of the [`item!`] macro allows the module that's used to be
723/// specified as the first argument. By default this is `rune`.
724///
725/// # Examples
726///
727/// ```
728/// use rune_core::item::{Item, ItemBuf};
729/// use rune_macros::item_in;
730///
731/// static ITEM: &Item = rune::item_in!(rune_core::item, ::std::ops::generator::Generator);
732///
733/// let mut item = ItemBuf::with_crate("std")?;
734/// item.push("ops")?;
735/// item.push("generator")?;
736/// item.push("Generator")?;
737///
738/// assert_eq!(item, ITEM);
739/// # Ok::<_, rune_core::alloc::Error>(())
740/// ```
741#[doc(inline)]
742pub use rune_macros::item_in;
743
744/// Macro used to annotate native functions which can be loaded as macros in
745/// rune.
746///
747/// See [`Module::macro_meta`][crate::Module::macro_meta].
748///
749/// # Examples
750///
751/// ```
752/// use rune::Module;
753/// use rune::ast;
754/// use rune::compile;
755/// use rune::macros::{quote, MacroContext, TokenStream};
756/// use rune::parse::Parser;
757/// use rune::alloc::prelude::*;
758///
759/// /// Takes an identifier and converts it into a string.
760/// ///
761/// /// # Examples
762/// ///
763/// /// ```rune
764/// /// assert_eq!(ident_to_string!(Hello), "Hello");
765/// /// ```
766/// #[rune::macro_]
767/// fn ident_to_string(cx: &mut MacroContext<'_, '_, '_>, stream: &TokenStream) -> compile::Result<TokenStream> {
768/// let mut p = Parser::from_token_stream(stream, cx.input_span());
769/// let ident = p.parse_all::<ast::Ident>()?;
770/// let ident = cx.resolve(ident)?.try_to_owned()?;
771/// let string = cx.lit(&ident)?;
772/// Ok(quote!(#string).into_token_stream(cx)?)
773/// }
774///
775/// let mut m = Module::new();
776/// m.macro_meta(ident_to_string)?;
777/// # Ok::<_, rune::support::Error>(())
778/// ```
779#[doc(inline)]
780pub use rune_macros::macro_;
781
782/// Macro used to annotate a module with metadata.
783///
784/// ThIs defines a local function `module_meta` which can be used in conjunction
785/// with [`Module::from_meta`] to construct a module with a given item and
786/// captured documentation.
787///
788/// [`Module::from_meta`]: crate::module::Module::from_meta
789///
790/// # Examples
791///
792/// ```
793/// use rune::{ContextError, Module};
794///
795/// /// Utilities for working with colors.
796/// #[rune::module(::color)]
797/// pub fn module() -> Result<Module, ContextError> {
798/// let mut m = Module::from_meta(module__meta)?;
799///
800/// // Populate module.
801///
802/// Ok(m)
803/// }
804/// ```
805#[doc(inline)]
806pub use rune_macros::module;
807
808#[cfg(feature = "cli")]
809mod ace;
810
811#[cfg(feature = "cli")]
812#[cfg_attr(rune_docsrs, doc(cfg(feature = "cli")))]
813pub mod cli;
814
815#[cfg(feature = "languageserver")]
816#[cfg_attr(rune_docsrs, doc(cfg(feature = "languageserver")))]
817pub mod languageserver;
818
819#[cfg(feature = "doc")]
820#[cfg_attr(rune_docsrs, doc(cfg(feature = "doc")))]
821pub(crate) mod doc;
822
823/// Privately exported details.
824#[doc(hidden)]
825pub mod __priv {
826 pub use crate::any::AnyMarker;
827 pub use crate::function_meta::{
828 FunctionMetaData, FunctionMetaKind, FunctionMetaStatics, MacroMetaData, MacroMetaKind,
829 };
830 pub use crate::item::{Item, ItemBuf};
831 pub use crate::module::{InstallWith, Module, ModuleMetaData};
832 pub use crate::params::Params;
833 pub use crate::runtime::{
834 AnyTypeInfo, ConstConstruct, ConstConstructImpl, ConstValue, FromConstValue, FromValue,
835 MaybeTypeOf, Object, OwnedTuple, Protocol, RawValueGuard, RuntimeError, ToConstValue,
836 ToValue, Tuple, TypeHash, TypeOf, TypeValue, UnsafeToMut, UnsafeToRef, UnsafeToValue,
837 Value, ValueMutGuard, ValueRefGuard, VmError,
838 };
839 pub use core::clone::Clone;
840
841 pub mod e {
842 use crate::alloc::borrow::TryToOwned;
843 use crate::runtime::{AnyTypeInfo, RuntimeError, TypeInfo, VmErrorKind};
844
845 #[doc(hidden)]
846 #[inline]
847 pub fn missing_struct_field(target: &'static str, name: &'static str) -> RuntimeError {
848 RuntimeError::new(VmErrorKind::MissingStructField { target, name })
849 }
850
851 #[doc(hidden)]
852 #[inline]
853 pub fn missing_variant(name: &str) -> RuntimeError {
854 match name.try_to_owned() {
855 Ok(name) => RuntimeError::new(VmErrorKind::MissingVariant { name }),
856 Err(error) => RuntimeError::from(error),
857 }
858 }
859
860 #[doc(hidden)]
861 #[inline]
862 pub fn expected_variant(actual: TypeInfo) -> RuntimeError {
863 RuntimeError::new(VmErrorKind::ExpectedVariant { actual })
864 }
865
866 #[doc(hidden)]
867 #[inline]
868 pub fn missing_variant_name() -> RuntimeError {
869 RuntimeError::new(VmErrorKind::MissingVariantName)
870 }
871
872 #[doc(hidden)]
873 #[inline]
874 pub fn missing_tuple_index(target: &'static str, index: usize) -> RuntimeError {
875 RuntimeError::new(VmErrorKind::MissingTupleIndex { target, index })
876 }
877
878 #[doc(hidden)]
879 #[inline]
880 pub fn unsupported_object_field_get(target: AnyTypeInfo) -> RuntimeError {
881 RuntimeError::new(VmErrorKind::UnsupportedObjectFieldGet {
882 target: TypeInfo::from(target),
883 })
884 }
885
886 #[doc(hidden)]
887 #[inline]
888 pub fn unsupported_tuple_index_get(target: AnyTypeInfo, index: usize) -> RuntimeError {
889 RuntimeError::new(VmErrorKind::UnsupportedTupleIndexGet {
890 target: TypeInfo::from(target),
891 index,
892 })
893 }
894 }
895}
896
897#[cfg(feature = "musli")]
898mod musli;
899#[cfg(feature = "serde")]
900mod serde;
901
902#[cfg(test)]
903mod tests;
904
905rune_macros::binding! {
906 impl ::std::string::String for crate::alloc::String;
907 #[cfg(feature = "std")]
908 #[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
909 impl ::std::io::Error for std::io::Error;
910 impl ::std::string::FromUtf8Error for crate::alloc::string::FromUtf8Error;
911 #[cfg(feature = "anyhow")]
912 impl ::std::error::Error for anyhow::Error;
913 impl ::std::fmt::Error for core::fmt::Error;
914 impl ::std::char::ParseCharError for core::char::ParseCharError;
915 impl ::std::num::ParseFloatError for core::num::ParseFloatError;
916 impl ::std::num::ParseIntError for core::num::ParseIntError;
917 impl ::std::string::Utf8Error for core::str::Utf8Error;
918 #[any]
919 impl ::std::option::Option for Option<Value>;
920 #[type_of]
921 impl<T> ::std::option::Option for Option<T>;
922 #[any]
923 impl ::std::result::Result for Result<Value, Value>;
924 #[type_of]
925 impl<T, E> ::std::result::Result for Result<T, E>;
926 #[type_of]
927 impl ::std::bool for bool;
928 #[type_of]
929 impl ::std::char for char;
930 #[type_of]
931 impl ::std::i64 for i8;
932 #[type_of]
933 impl ::std::i64 for i16;
934 #[type_of]
935 impl ::std::i64 for i32;
936 #[type_of]
937 impl ::std::i64 for i64;
938 #[type_of]
939 impl ::std::i64 for i128;
940 #[type_of]
941 impl ::std::i64 for isize;
942 #[type_of]
943 impl ::std::u64 for u8;
944 #[type_of]
945 impl ::std::u64 for u16;
946 #[type_of]
947 impl ::std::u64 for u32;
948 #[type_of]
949 impl ::std::u64 for u64;
950 #[type_of]
951 impl ::std::u64 for u128;
952 #[type_of]
953 impl ::std::u64 for usize;
954 #[type_of]
955 impl ::std::f64 for f32;
956 #[type_of]
957 impl ::std::f64 for f64;
958 #[type_of]
959 impl<C, B> ::std::ops::ControlFlow for core::ops::ControlFlow<C, B>;
960 #[type_of]
961 impl ::std::bytes::Bytes for [u8];
962 #[type_of]
963 impl ::std::cmp::Ordering for core::cmp::Ordering;
964 #[type_of]
965 impl ::std::string::String for rust_alloc::string::String;
966 #[type_of]
967 impl ::std::string::String for crate::alloc::Box<str>;
968 #[type_of]
969 impl ::std::string::String for str;
970 #[type_of]
971 impl ::std::vec::Vec for [Value];
972 #[type_of]
973 impl<T> ::std::vec::Vec for rust_alloc::vec::Vec<T>;
974 #[type_of]
975 impl<T> ::std::vec::Vec for crate::alloc::Vec<T>;
976 #[type_of]
977 impl<T, const N: usize> ::std::vec::Vec for [T; N];
978 #[type_of]
979 impl<T> ::std::vec::Vec for crate::runtime::VecTuple<T>;
980 #[type_of]
981 impl ::std::tuple::Tuple for crate::runtime::Tuple;
982 #[type_of]
983 impl<T> ::std::object::Object for crate::alloc::HashMap<rust_alloc::string::String, T>;
984 #[type_of]
985 impl<T> ::std::object::Object for crate::alloc::HashMap<alloc::String, T>;
986 #[type_of]
987 #[cfg(feature = "std")]
988 #[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
989 impl<T> ::std::object::Object for std::collections::HashMap<rust_alloc::string::String, T>;
990 #[type_of]
991 #[cfg(feature = "std")]
992 #[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
993 impl<T> ::std::object::Object for std::collections::HashMap<alloc::String, T>;
994 #[type_of]
995 impl ::std::any::Type for crate::runtime::Type;
996 #[type_of]
997 impl ::std::any::Hash for crate::hash::Hash;
998}
999
1000vm_error!(crate::alloc::Error);