rune/modules/core.rs
1//! Core types and methods in Rune.
2
3use crate as rune;
4use crate::alloc::prelude::*;
5use crate::compile;
6use crate::macros::{quote, FormatArgs, MacroContext, TokenStream};
7use crate::runtime::{Value, VmError};
8use crate::{docstring, ContextError, Module};
9
10/// Core types and methods in Rune.
11///
12/// These are types and methods for which Rune as a language would not work without.
13#[rune::module(::std)]
14pub fn module() -> Result<Module, ContextError> {
15 let mut module = Module::from_meta(self::module__meta)?.with_unique("std");
16
17 module.ty::<bool>()?.docs(docstring! {
18 /// The primitive boolean type.
19 })?;
20 module.ty::<char>()?.docs(docstring! {
21 /// The primitive character type.
22 })?;
23 module.ty::<u64>()?.docs(docstring! {
24 /// The unsigned integer type.
25 })?;
26 module.ty::<i64>()?.docs(docstring! {
27 /// The signed integer type.
28 })?;
29 module.ty::<f64>()?.docs(docstring! {
30 /// The primitive float type.
31 })?;
32
33 module.function_meta(panic)?;
34 module.function_meta(is_readable)?;
35 module.function_meta(is_writable)?;
36
37 module.macro_meta(stringify_macro)?;
38 module.macro_meta(panic_macro)?;
39 Ok(module)
40}
41
42/// Cause a vm panic with the given `message`.
43///
44/// A panic in Rune causes the current execution to unwind and terminate. The
45/// panic will not be propagated into Rust, but will instead be signatted
46/// through a `VmError`.
47///
48/// If you want to format a message, consider using the [panic!] macro.
49#[rune::function]
50fn panic(message: &str) -> Result<(), VmError> {
51 Err(VmError::panic(message.try_to_owned()?))
52}
53
54/// Test if the given `value` is readable.
55///
56/// A value is readable if can be acquired for shared access, such as producing
57/// an immutable reference.
58///
59/// A value that is moved is no longer considered readable.
60///
61/// # Examples
62///
63/// ```rune
64/// let value = Some(42);
65/// assert!(is_readable(value));
66/// let value2 = value.map(|v| v + 1);
67/// drop(value);
68/// assert!(!is_readable(value));
69/// assert_eq!(value2, Some(43));
70/// ```
71#[rune::function]
72fn is_readable(value: Value) -> bool {
73 value.is_readable()
74}
75
76/// Test if the given `value` is writable.
77///
78/// A value is writable if can be acquired for exclusive access, such as
79/// producing a mutable reference or taking ownership.
80///
81/// # Examples
82///
83/// ```rune
84/// let value = Some(42);
85/// assert!(is_writable(value));
86/// let value2 = value.map(|v| v + 1);
87/// drop(value);
88/// assert!(!is_writable(value));
89/// assert_eq!(value2, Some(43));
90/// ```
91#[rune::function]
92fn is_writable(value: Value) -> bool {
93 value.is_writable()
94}
95
96/// Stringify the given argument, causing it to expand to its underlying token
97/// stream.
98///
99/// This can be used by macros to convert a stream of tokens into a readable
100/// string.
101#[rune::macro_(path = stringify)]
102pub(crate) fn stringify_macro(
103 cx: &mut MacroContext<'_, '_, '_>,
104 stream: &TokenStream,
105) -> compile::Result<TokenStream> {
106 let lit = cx.stringify(stream)?.try_to_string()?;
107 let lit = cx.lit(lit)?;
108 Ok(quote!(#lit).into_token_stream(cx)?)
109}
110
111/// Cause a vm panic with a formatted message.
112///
113/// A panic in Rune causes the current execution to unwind and terminate. The
114/// panic will not be propagated into Rust, but will instead be signatted
115/// through a `VmError`.
116#[rune::macro_(path = panic)]
117pub(crate) fn panic_macro(
118 cx: &mut MacroContext<'_, '_, '_>,
119 stream: &TokenStream,
120) -> compile::Result<TokenStream> {
121 let mut p = cx.parser(stream, cx.input_span());
122 let args = p.parse_all::<FormatArgs>()?;
123 let expanded = args.expand(cx)?;
124 Ok(quote!(::std::panic(#expanded)).into_token_stream(cx)?)
125}